Fix keystore_cli_v2
With asynchronous keystore we need a binder thread to take the callback
from keystore.
Bug: 111443219
Test: manually tested by calling keystore_cli_v2
Change-Id: Ibac2d3d176090bbfd1548899bf670d83d3ab6215
diff --git a/keystore/keystore_cli_v2.cpp b/keystore/keystore_cli_v2.cpp
index 0981f1e..1c94318 100644
--- a/keystore/keystore_cli_v2.cpp
+++ b/keystore/keystore_cli_v2.cpp
@@ -12,7 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <chrono>
#include <cstdio>
+#include <future>
#include <memory>
#include <string>
#include <vector>
@@ -460,33 +462,17 @@
return KEYSTORE_FLAG_NONE;
}
-class ConfirmationListener : public android::security::BnConfirmationPromptCallback {
+class ConfirmationListener
+ : public android::security::BnConfirmationPromptCallback,
+ public std::promise<std::tuple<ConfirmationResponseCode, std::vector<uint8_t>>> {
public:
ConfirmationListener() {}
virtual ::android::binder::Status
onConfirmationPromptCompleted(int32_t result,
const ::std::vector<uint8_t>& dataThatWasConfirmed) override {
- ConfirmationResponseCode responseCode = static_cast<ConfirmationResponseCode>(result);
- printf("Confirmation prompt completed\n"
- "responseCode = %d\n",
- responseCode);
- printf("dataThatWasConfirmed[%zd] = {", dataThatWasConfirmed.size());
- size_t newLineCountDown = 16;
- bool hasPrinted = false;
- for (uint8_t element : dataThatWasConfirmed) {
- if (hasPrinted) {
- printf(", ");
- }
- if (newLineCountDown == 0) {
- printf("\n ");
- newLineCountDown = 32;
- }
- printf("0x%02x", element);
- hasPrinted = true;
- }
- printf("}\n");
- exit(0);
+ this->set_value({static_cast<ConfirmationResponseCode>(result), dataThatWasConfirmed});
+ return ::android::binder::Status::ok();
}
};
@@ -536,6 +522,7 @@
sp<ConfirmationListener> listener = new ConfirmationListener();
+ auto future = listener->get_future();
int32_t aidl_return;
android::binder::Status status = service->presentConfirmationPrompt(
listener, promptText16, extraData, locale16, uiOptionsAsFlags, &aidl_return);
@@ -549,26 +536,53 @@
printf("Presenting confirmation prompt failed with response code %d.\n", responseCode);
return 1;
}
+ printf("Waiting for prompt to complete - use Ctrl+C to abort...\n");
if (cancelAfterValue > 0.0) {
printf("Sleeping %.1f seconds before canceling prompt...\n", cancelAfterValue);
- base::PlatformThread::Sleep(base::TimeDelta::FromSecondsD(cancelAfterValue));
- status = service->cancelConfirmationPrompt(listener, &aidl_return);
- if (!status.isOk()) {
- printf("Canceling confirmation prompt failed with binder status '%s'.\n",
- status.toString8().c_str());
- return 1;
- }
- responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
- if (responseCode != ConfirmationResponseCode::OK) {
- printf("Canceling confirmation prompt failed with response code %d.\n", responseCode);
- return 1;
+ auto fstatus =
+ future.wait_for(std::chrono::milliseconds(uint64_t(cancelAfterValue * 1000)));
+ if (fstatus == std::future_status::timeout) {
+ status = service->cancelConfirmationPrompt(listener, &aidl_return);
+ if (!status.isOk()) {
+ printf("Canceling confirmation prompt failed with binder status '%s'.\n",
+ status.toString8().c_str());
+ return 1;
+ }
+ responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
+ if (responseCode == ConfirmationResponseCode::Ignored) {
+ // The confirmation was completed by the user so take the response
+ } else if (responseCode != ConfirmationResponseCode::OK) {
+ printf("Canceling confirmation prompt failed with response code %d.\n",
+ responseCode);
+ return 1;
+ }
}
}
- printf("Waiting for prompt to complete - use Ctrl+C to abort...\n");
- // Use the main thread to process Binder transactions.
- android::IPCThreadState::self()->joinThreadPool();
+ future.wait();
+
+ auto [rc, dataThatWasConfirmed] = future.get();
+
+ printf("Confirmation prompt completed\n"
+ "responseCode = %d\n",
+ rc);
+ printf("dataThatWasConfirmed[%zd] = {", dataThatWasConfirmed.size());
+ size_t newLineCountDown = 16;
+ bool hasPrinted = false;
+ for (uint8_t element : dataThatWasConfirmed) {
+ if (hasPrinted) {
+ printf(", ");
+ }
+ if (newLineCountDown == 0) {
+ printf("\n ");
+ newLineCountDown = 32;
+ }
+ printf("0x%02x", element);
+ hasPrinted = true;
+ }
+ printf("}\n");
+
return 0;
}
@@ -578,6 +592,10 @@
CommandLine::Init(argc, argv);
CommandLine* command_line = CommandLine::ForCurrentProcess();
CommandLine::StringVector args = command_line->GetArgs();
+
+ std::thread thread_pool([] { android::IPCThreadState::self()->joinThreadPool(false); });
+ thread_pool.detach();
+
if (args.empty()) {
PrintUsageAndExit();
}