diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
index fd8819a..5574465 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
@@ -85,6 +85,8 @@
 import com.google.android.car.kitchensink.watchdog.CarWatchdogTestFragment;
 import com.google.android.car.kitchensink.weblinks.WebLinksTestFragment;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
@@ -401,6 +403,17 @@
         super.onDestroy();
     }
 
+    @Override
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        if (args != null && args.length > 0 && args[0].equals("cmd")) {
+            String[] cmdArgs = new String[args.length - 1];
+            System.arraycopy(args, 1, cmdArgs, 0, args.length - 1);
+            new KitchenSinkShellCommand(this, writer, cmdArgs).run();
+            return;
+        }
+        super.dump(prefix, fd, writer, args);
+    }
+
     private void showFragment(Fragment fragment) {
         getSupportFragmentManager().beginTransaction()
                 .replace(R.id.kitchen_content, fragment)
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkShellCommand.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkShellCommand.java
new file mode 100644
index 0000000..d72765e
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkShellCommand.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.android.car.kitchensink;
+
+import android.annotation.Nullable;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.security.AttestedKeyPair;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
+
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * {@code KitchenSink}'s own {@code cmd} implementation.
+ *
+ * <p>Usage: {$code adb shell dumpsys activity
+ * com.google.android.car.kitchensink/.KitchenSinkActivity cmd <CMD>}
+ *
+ * <p><p>Note</p>: you must launch {@code KitchenSink} first. Example: {@code
+ * adb shell am start com.google.android.car.kitchensink/.KitchenSinkActivity}
+ */
+final class KitchenSinkShellCommand {
+
+    private static final String TAG = "KitchenSinkCmd";
+
+    private static final String CMD_HELP = "help";
+    private static final String CMD_GET_DELEGATED_SCOPES = "get-delegated-scopes";
+    private static final String CMD_IS_UNINSTALL_BLOCKED = "is-uninstall-blocked";
+    private static final String CMD_SET_UNINSTALL_BLOCKED = "set-uninstall-blocked";
+    private static final String CMD_GENERATE_DEVICE_ATTESTATION_KEY_PAIR =
+            "generate-device-attestation-key-pair";
+
+    private final Context mContext;
+    private final @Nullable DevicePolicyManager mDpm;
+    private final IndentingPrintWriter mWriter;
+    private final String[] mArgs;
+
+    @Nullable // dynamically created on post() method
+    private Handler mHandler;
+
+    private int mNextArgIndex;
+
+    KitchenSinkShellCommand(Context context, PrintWriter writer, String[] args) {
+        mContext = context;
+        mDpm = context.getSystemService(DevicePolicyManager.class);
+        mWriter = new IndentingPrintWriter(writer);
+        mArgs = args;
+    }
+
+    void run() {
+        if (mArgs.length == 0) {
+            showHelp("Error: must pass an argument");
+            return;
+        }
+        String cmd = mArgs[0];
+        switch (cmd) {
+            case CMD_HELP:
+                showHelp("KitchenSink Command-Line Interface");
+                break;
+            case CMD_GET_DELEGATED_SCOPES:
+                getDelegatedScopes();
+                break;
+            case CMD_IS_UNINSTALL_BLOCKED:
+                isUninstallBlocked();
+                break;
+            case CMD_SET_UNINSTALL_BLOCKED:
+                setUninstallBlocked();
+                break;
+            case CMD_GENERATE_DEVICE_ATTESTATION_KEY_PAIR:
+                generateDeviceAttestationKeyPair();
+                break;
+            default:
+                showHelp("Invalid command: %s", cmd);
+        }
+    }
+
+    private void showHelp(String headerMessage, Object... headerArgs) {
+        if (headerMessage != null) {
+            mWriter.printf(headerMessage, headerArgs);
+            mWriter.print(". ");
+        }
+        mWriter.println("Available commands:\n");
+
+        mWriter.increaseIndent();
+        showCommandHelp("Shows this help message.",
+                CMD_HELP);
+        showCommandHelp("Lists delegated scopes set by the device admin.",
+                CMD_GET_DELEGATED_SCOPES);
+        showCommandHelp("Checks whether uninstalling the given app is blocked.",
+                CMD_IS_UNINSTALL_BLOCKED, "<PKG>");
+        showCommandHelp("Blocks / unblocks uninstalling the given app.",
+                CMD_SET_UNINSTALL_BLOCKED, "<PKG>", "<true|false>");
+        showCommandHelp("Generates a device attestation key.",
+                CMD_GENERATE_DEVICE_ATTESTATION_KEY_PAIR, "<ALIAS>", "[FLAGS]");
+        mWriter.decreaseIndent();
+    }
+
+    private void showCommandHelp(String description, String cmd, String... args) {
+        mWriter.printf("%s", cmd);
+        if (args != null) {
+            for (String arg : args) {
+                mWriter.printf(" %s", arg);
+            }
+        }
+        mWriter.println(":");
+        mWriter.increaseIndent();
+        mWriter.printf("%s\n\n", description);
+        mWriter.decreaseIndent();
+    }
+
+    private void getDelegatedScopes() {
+        if (!supportDevicePolicyManagement()) return;
+
+        List<String> scopes = mDpm.getDelegatedScopes(/* admin= */ null, mContext.getPackageName());
+        printCollection("delegated scope", scopes);
+    }
+
+    private void isUninstallBlocked() {
+        if (!supportDevicePolicyManagement()) return;
+
+        String packageName = getNextArg();
+        boolean isIt = mDpm.isUninstallBlocked(/* admin= */ null, packageName);
+        mWriter.println(isIt);
+    }
+
+    private void setUninstallBlocked() {
+        if (!supportDevicePolicyManagement()) return;
+
+        String packageName = getNextArg();
+        boolean blocked = getNextBooleanArg();
+
+        Log.i(TAG, "Calling dpm.setUninstallBlocked(" + packageName + ", " + blocked + ")");
+        mDpm.setUninstallBlocked(/* admin= */ null, packageName, blocked);
+    }
+
+    private void generateDeviceAttestationKeyPair() {
+        if (!supportDevicePolicyManagement()) return;
+
+        String alias = getNextArg();
+        int flags = getNextOptionalIntArg(/* defaultValue= */ 0);
+        // Cannot call dpm.generateKeyPair() on main thread
+        warnAboutAsyncCall();
+        post(() -> handleDeviceAttestationKeyPair(alias, flags));
+    }
+
+    private void handleDeviceAttestationKeyPair(String alias, int flags) {
+        KeyGenParameterSpec keySpec = buildRsaKeySpecWithKeyAttestation(alias);
+        String algorithm = "RSA";
+        Log.i(TAG, "calling dpm.generateKeyPair(alg=" + algorithm + ", spec=" + keySpec
+                + ", flags=" + flags + ")");
+        AttestedKeyPair kp = mDpm.generateKeyPair(/* admin= */ null, algorithm, keySpec, flags);
+        Log.i(TAG, "key: " + kp);
+    }
+
+    private void warnAboutAsyncCall() {
+        mWriter.printf("Command will be executed asynchronally; use `adb logcat %s *:s` for result"
+                + "\n", TAG);
+    }
+
+    private void post(Runnable r) {
+        if (mHandler == null) {
+            HandlerThread handlerThread = new HandlerThread("KitchenSinkShellCommandThread");
+            Log.i(TAG, "Starting " + handlerThread);
+            handlerThread.start();
+            mHandler = new Handler(handlerThread.getLooper());
+        }
+        Log.d(TAG, "posting runnable");
+        mHandler.post(r);
+    }
+
+    private boolean supportDevicePolicyManagement() {
+        if (mDpm == null) {
+            mWriter.println("Device Policy Management not supported by device");
+            return false;
+        }
+        return true;
+    }
+
+    private String getNextArgAndIncrementCounter() {
+        return mArgs[++mNextArgIndex];
+    }
+
+    private String getNextArg() {
+        try {
+            return getNextArgAndIncrementCounter();
+        } catch (Exception e) {
+            mWriter.println("Error: missing argument");
+            mWriter.flush();
+            throw new IllegalArgumentException(
+                    "Missing argument. Args=" + Arrays.toString(mArgs));
+        }
+    }
+
+    private int getNextOptionalIntArg(int defaultValue) {
+        try {
+            return Integer.parseInt(getNextArgAndIncrementCounter());
+        } catch (Exception e) {
+            Log.d(TAG, "Exception getting optional arg: " + e);
+            return defaultValue;
+        }
+    }
+
+    private boolean getNextBooleanArg() {
+        String arg = getNextArg();
+        return Boolean.parseBoolean(arg);
+    }
+
+    private void printCollection(String nameOnSingular, Collection<String> collection) {
+        if (collection.isEmpty()) {
+            mWriter.printf("No %ss\n", nameOnSingular);
+            return;
+        }
+        int size = collection.size();
+        mWriter.printf("%d %s%s:\n", size, nameOnSingular, size == 1 ? "" : "s");
+        collection.forEach((s) -> mWriter.printf("  %s\n", s));
+    }
+
+    // Copied from CTS' KeyGenerationUtils
+    private static KeyGenParameterSpec buildRsaKeySpecWithKeyAttestation(String alias) {
+        return new KeyGenParameterSpec.Builder(alias,
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+                        .setKeySize(2048)
+                        .setDigests(KeyProperties.DIGEST_SHA256)
+                        .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS,
+                                KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+                        .setIsStrongBoxBacked(false)
+                        .setAttestationChallenge(new byte[] {
+                                'a', 'b', 'c'
+                        })
+                        .build();
+    }
+}
