blob: de0e1718ab0e2b6ccb7027645d641727e067f698 [file] [log] [blame]
Carlos Martinez Romero5ec086e2023-02-14 00:44:36 +00001/*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <inttypes.h>
17#include <stdint.h>
18#include <any>
Carlos Martinez Romerob4ea9e62023-10-25 21:48:56 +000019#include <map>
Carlos Martinez Romero5ec086e2023-02-14 00:44:36 +000020
21#include <cutils/properties.h>
22#include <sys/resource.h>
23#include <utils/Log.h>
24
25#include <gui/ISurfaceComposer.h>
26#include <gui/SurfaceComposerClient.h>
27#include <gui/SurfaceControl.h>
28#include <private/gui/ComposerServiceAIDL.h>
29
30using namespace android;
31
Carlos Martinez Romerob4ea9e62023-10-25 21:48:56 +000032std::map<std::string, std::any> g_functions;
Carlos Martinez Romero5ec086e2023-02-14 00:44:36 +000033
Carlos Martinez Romerob4ea9e62023-10-25 21:48:56 +000034enum class ParseToggleResult {
35 kError,
36 kFalse,
37 kTrue,
38};
39
40const std::map<std::string, std::string> g_function_details = {
41 {"debugFlash", "[optional(delay)] Perform a debug flash."},
42 {"frameRateIndicator", "[hide | show] displays the framerate in the top left corner."},
43 {"scheduleComposite", "Force composite ahead of next VSYNC."},
44 {"scheduleCommit", "Force commit ahead of next VSYNC."},
45 {"scheduleComposite", "PENDING - if you have a good understanding let me know!"},
46 {"forceClientComposition",
47 "[enabled | disabled] When enabled, it disables "
48 "Hardware Overlays, and routes all window composition to the GPU. This can "
49 "help check if there is a bug in HW Composer."},
Carlos Martinez Romero5ec086e2023-02-14 00:44:36 +000050};
51
52static void ShowUsage() {
Carlos Martinez Romero42dc9e92023-11-06 13:56:00 -080053 std::cout << "usage: sfdo [help, frameRateIndicator show, debugFlash enabled, ...]\n\n";
Carlos Martinez Romero5ec086e2023-02-14 00:44:36 +000054 for (const auto& sf : g_functions) {
55 const std::string fn = sf.first;
56 std::string fdetails = "TODO";
57 if (g_function_details.find(fn) != g_function_details.end())
58 fdetails = g_function_details.find(fn)->second;
59 std::cout << " " << fn << ": " << fdetails << "\n";
60 }
61}
62
Carlos Martinez Romerob4ea9e62023-10-25 21:48:56 +000063// Returns 1 for positive keywords and 0 for negative keywords.
64// If the string does not match any it will return -1.
65ParseToggleResult parseToggle(const char* str) {
66 const std::unordered_set<std::string> positive{"1", "true", "y", "yes",
67 "on", "enabled", "show"};
68 const std::unordered_set<std::string> negative{"0", "false", "n", "no",
69 "off", "disabled", "hide"};
70
71 const std::string word(str);
72 if (positive.count(word)) {
73 return ParseToggleResult::kTrue;
74 }
75 if (negative.count(word)) {
76 return ParseToggleResult::kFalse;
77 }
78
79 return ParseToggleResult::kError;
80}
81
Carlos Martinez Romero42dc9e92023-11-06 13:56:00 -080082int frameRateIndicator(int argc, char** argv) {
Carlos Martinez Romero5ec086e2023-02-14 00:44:36 +000083 bool hide = false, show = false;
84 if (argc == 3) {
85 show = strcmp(argv[2], "show") == 0;
86 hide = strcmp(argv[2], "hide") == 0;
87 }
88
89 if (show || hide) {
90 ComposerServiceAIDL::getComposerService()->enableRefreshRateOverlay(show);
91 } else {
Carlos Martinez Romero42dc9e92023-11-06 13:56:00 -080092 std::cerr << "Incorrect usage of frameRateIndicator. Missing [hide | show].\n";
Carlos Martinez Romero5ec086e2023-02-14 00:44:36 +000093 return -1;
94 }
95 return 0;
96}
97
Carlos Martinez Romero42dc9e92023-11-06 13:56:00 -080098int debugFlash(int argc, char** argv) {
Carlos Martinez Romero5ec086e2023-02-14 00:44:36 +000099 int delay = 0;
100 if (argc == 3) {
101 delay = atoi(argv[2]) == 0;
102 }
103
104 ComposerServiceAIDL::getComposerService()->setDebugFlash(delay);
105 return 0;
106}
107
108int scheduleComposite([[maybe_unused]] int argc, [[maybe_unused]] char** argv) {
109 ComposerServiceAIDL::getComposerService()->scheduleComposite();
110 return 0;
111}
112
113int scheduleCommit([[maybe_unused]] int argc, [[maybe_unused]] char** argv) {
114 ComposerServiceAIDL::getComposerService()->scheduleCommit();
115 return 0;
116}
117
Carlos Martinez Romerob4ea9e62023-10-25 21:48:56 +0000118int forceClientComposition(int argc, char** argv) {
119 bool enabled = true;
120 // A valid command looks like this:
121 // adb shell sfdo forceClientComposition enabled
122 if (argc >= 3) {
123 const ParseToggleResult toggle = parseToggle(argv[2]);
124 if (toggle == ParseToggleResult::kError) {
125 std::cerr << "Incorrect usage of forceClientComposition. "
126 "Missing [enabled | disabled].\n";
127 return -1;
128 }
129 if (argc > 3) {
130 std::cerr << "Too many arguments after [enabled | disabled]. "
131 "Ignoring extra arguments.\n";
132 }
133 enabled = (toggle == ParseToggleResult::kTrue);
134 } else {
135 std::cerr << "Incorrect usage of forceClientComposition. Missing [enabled | disabled].\n";
136 return -1;
137 }
138
139 ComposerServiceAIDL::getComposerService()->forceClientComposition(enabled);
140 return 0;
141}
142
Carlos Martinez Romero5ec086e2023-02-14 00:44:36 +0000143int main(int argc, char** argv) {
144 std::cout << "Execute SurfaceFlinger internal commands.\n";
145 std::cout << "sfdo requires to be run with root permissions..\n";
146
Carlos Martinez Romero42dc9e92023-11-06 13:56:00 -0800147 g_functions["frameRateIndicator"] = frameRateIndicator;
148 g_functions["debugFlash"] = debugFlash;
Carlos Martinez Romero5ec086e2023-02-14 00:44:36 +0000149 g_functions["scheduleComposite"] = scheduleComposite;
150 g_functions["scheduleCommit"] = scheduleCommit;
Carlos Martinez Romerob4ea9e62023-10-25 21:48:56 +0000151 g_functions["forceClientComposition"] = forceClientComposition;
Carlos Martinez Romero5ec086e2023-02-14 00:44:36 +0000152
153 if (argc > 1 && g_functions.find(argv[1]) != g_functions.end()) {
154 std::cout << "Running: " << argv[1] << "\n";
155 const std::string key(argv[1]);
156 const auto fn = g_functions[key];
157 int result = std::any_cast<int (*)(int, char**)>(fn)(argc, argv);
158 if (result == 0) {
159 std::cout << "Success.\n";
160 }
161 return result;
162 } else {
163 ShowUsage();
164 }
165 return 0;
166}