diff --git a/README.md b/README.md index 99e1bcec4..5b0eaf309 100644 --- a/README.md +++ b/README.md @@ -93,8 +93,49 @@ And on Windows, Open Developer Command Prompt for VS 2022(or 2019) and run scripts\build_android.bat ``` +It will build both debug and release version of the libraries under `build_android` folder. +### CLI Tool for capture and cleanup +#### Capture with command line tool for Android applications +Currently the command line tool supports capture OpenXR and Vulkan applications on Android. To Get a capture, please refer to the above sections to checkout the code and build the Android libraries. In addition to that, you'll need to build and install the CLI tool. -It will build both debug and release version of the libraries under `build_android` folder. +On Linux, run: +``` +./scripts/build_android.sh +``` +``` +mkdir build +cd build +cmake -GNinja .. +ninja +ninja install +``` + +And the libraries and CLI will be installed under the `install` folder. +Run `./dive_client_cli --help` for help. + +You can find out the device serial by run `adb devices` or by `./dive_client_cli --command list_device` + +Examples: + - Install the dependencies on device and start the package and do a capture after the applications runs 5 seconds. + ``` + ./dive_client_cli --device 9A221FFAZ004TL --command capture --package de.saschawillems.vulkanBloom --type vulkan --capture_path "~/captures" + ``` + + - Install the dependencies on device and start the package + ``` + ./dive_client_cli --device 9A221FFAZ004TL --command run --package com.google.bigwheels.project_04_cube_xr.debug --type openxr --capture_path "~/captures" + ``` +Then you can follow the hint output to trigger a capture by press key `t` and `enter` or exit by press key `enter` only. +The capture files will be saved at the path specified with the `--capture_path` option or the current directory if this option not specified. + +#### Cleanup + +The command line tool will clean up the device and application automatically at exit. If somehow it crashed and left the device in a uncleaned state, you can run following command to clean it up + +``` +./dive_client_cli --command cleanup --package de.saschawillems.vulkanBloom --device 9A221FFAZ004TL +``` +This will remove all the libraries installed and the settings that had been setup by Dive for the package. diff --git a/capture_service/dive_client_cli.cc b/capture_service/dive_client_cli.cc index 51d9652ff..c4990f85b 100644 --- a/capture_service/dive_client_cli.cc +++ b/capture_service/dive_client_cli.cc @@ -16,6 +16,7 @@ limitations under the License. #include #include +#include #include #include #include @@ -100,10 +101,15 @@ ABSL_FLAG(Command, ABSL_FLAG(std::string, target, "localhost:19999", "Server address"); ABSL_FLAG(std::string, device, "", "Device serial"); ABSL_FLAG(std::string, package, "", "Package on the device"); -ABSL_FLAG(int, - type, - 0, - "application type: \n\t0 for OpenXR applications \n\t 1 for Vulkan applications"); +ABSL_FLAG( +std::string, +type, +"openxr", +"application type: \n\t`openxr` for OpenXR applications \n\t `vulkan` for Vulkan applications"); +ABSL_FLAG(std::string, + capture_path, + ".", + "specify the full path to save the capture, default to current directory"); void print_usage() { @@ -143,7 +149,7 @@ bool list_package(Dive::DeviceManager& mgr, const std::string& device_serial) return true; } -bool run_package(Dive::DeviceManager& mgr, const std::string& package, const int app_type) +bool run_package(Dive::DeviceManager& mgr, const std::string& package, const std::string& app_type) { std::string serial = absl::GetFlag(FLAGS_device); @@ -153,34 +159,55 @@ bool run_package(Dive::DeviceManager& mgr, const std::string& package, const int return false; } auto dev = mgr.SelectDevice(serial); - if (app_type == 0) + if (app_type == "openxr") dev->SetupApp(package, Dive::ApplicationType::OPENXR); - else if (app_type == 1) + else if (app_type == "vulkan") dev->SetupApp(package, Dive::ApplicationType::VULKAN); - + else + { + print_usage(); + return false; + } dev->StartApp(); return true; } -bool run_and_capture(Dive::DeviceManager& mgr, const std::string& package) +bool trigger_capture(Dive::DeviceManager& mgr) { - std::string target_str = absl::GetFlag(FLAGS_target); - int app_type = absl::GetFlag(FLAGS_type); - run_package(mgr, package, app_type); + std::string capture_path = absl::GetFlag(FLAGS_capture_path); + std::string input; Dive::DiveClient client(grpc::CreateChannel(target_str, grpc::InsecureChannelCredentials())); - std::this_thread::sleep_for(2000ms); std::cout << "TestConnection reply: " << client.TestConnection() << std::endl; std::string trace_file_path = client.RequestStartTrace(); std::cout << "Trigger capture: " << trace_file_path << std::endl; - std::this_thread::sleep_for(5s); - mgr.GetDevice()->RetrieveTraceFile(trace_file_path, "."); + std::filesystem::path p(trace_file_path); + std::filesystem::path target(capture_path); + target /= p.filename(); + mgr.GetDevice()->RetrieveTraceFile(trace_file_path, target.generic_string()); + std::cout << "Capture saved at " << target << std::endl; - std::this_thread::sleep_for(2000ms); - std::cout << "TestConnection reply: " << client.TestConnection() << std::endl; + return true; +} + +bool run_and_capture(Dive::DeviceManager& mgr, const std::string& package) +{ + + std::string target_str = absl::GetFlag(FLAGS_target); + std::string app_type = absl::GetFlag(FLAGS_type); + run_package(mgr, package, app_type); + std::this_thread::sleep_for(5000ms); + trigger_capture(mgr); + + std::cout << "Press Enter to exit" << std::endl; + std::string input; + if (std::getline(std::cin, input)) + { + std::cout << "Exiting..." << std::endl; + } return true; } @@ -201,6 +228,28 @@ bool clean_up_app_and_device(Dive::DeviceManager& mgr, const std::string& packag return true; } +bool process_input(Dive::DeviceManager& mgr) +{ + std::cout << "Press key t+enter to trigger a capture. \nPress any other key + enter to exit."; + + std::string input; + while (std::getline(std::cin, input)) + { + if (input == "t") + { + std::cout << "key t pressed " << std::endl; + trigger_capture(mgr); + } + else + { + break; + } + std::cout << "Press key t+enter to trigger a capture. \nPress enter to exit."; + } + + return true; +} + int main(int argc, char** argv) { absl::SetProgramUsageMessage("Run app with --help for more details"); @@ -209,7 +258,7 @@ int main(int argc, char** argv) Command cmd = absl::GetFlag(FLAGS_command); std::string serial = absl::GetFlag(FLAGS_device); std::string package = absl::GetFlag(FLAGS_package); - int app_type = absl::GetFlag(FLAGS_type); + std::string app_type = absl::GetFlag(FLAGS_type); Dive::DeviceManager mgr; auto list = mgr.ListDevice(); @@ -234,7 +283,11 @@ int main(int argc, char** argv) case Command::kRunPackage: { - run_package(mgr, package, app_type); + if (run_package(mgr, package, app_type)) + { + process_input(mgr); + } + break; } @@ -254,11 +307,4 @@ int main(int argc, char** argv) break; } } - - std::cout << "Press Enter to exit" << std::endl; - std::string input; - if (std::getline(std::cin, input)) - { - std::cout << "Exiting..." << std::endl; - } }