Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d28177c7 authored by lpeter's avatar lpeter
Browse files

Provide the way to enable/disable debug mode for logging egressed data

Currently we provide the Shell command to enable/disable one debug mode
that we will log the HotwordDetectedResult and HotwordRejectedResult if
the debug mode is wnable. But we will reset the debug mode after one
hour from last enable.

Bug: 194339253
Test: Use the Shell command and check the log
Change-Id: I212ad58c7550b297babed50249a08db6f0e24b3a
parent 2d28217d
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ final class HotwordDetectionConnection {
    private static final long MAX_UPDATE_TIMEOUT_MILLIS = 6000;
    private static final Duration MAX_UPDATE_TIMEOUT_DURATION =
            Duration.ofMillis(MAX_UPDATE_TIMEOUT_MILLIS);
    private static final long RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour

    private final Executor mAudioCopyExecutor = Executors.newCachedThreadPool();
    // TODO: This may need to be a Handler(looper)
@@ -114,6 +115,7 @@ final class HotwordDetectionConnection {
    private Instant mLastRestartInstant;

    private ScheduledFuture<?> mCancellationTaskFuture;
    private ScheduledFuture<?> mDebugHotwordLoggingTimeoutFuture = null;

    /** Identity used for attributing app ops when delivering data to the Interactor. */
    @GuardedBy("mLock")
@@ -127,6 +129,7 @@ final class HotwordDetectionConnection {
    private boolean mPerformingSoftwareHotwordDetection;
    private @NonNull ServiceConnection mRemoteHotwordDetectionService;
    private IBinder mAudioFlinger;
    private boolean mDebugHotwordLogging = false;

    HotwordDetectionConnection(Object lock, Context context, int voiceInteractionServiceUid,
            Identity voiceInteractorIdentity, ComponentName serviceName, int userId,
@@ -265,6 +268,8 @@ final class HotwordDetectionConnection {

    void cancelLocked() {
        Slog.v(TAG, "cancelLocked");
        clearDebugHotwordLoggingTimeoutLocked();
        mDebugHotwordLogging = false;
        if (mRemoteHotwordDetectionService.isBound()) {
            mRemoteHotwordDetectionService.unbind();
            LocalServices.getService(PermissionManagerServiceInternal.class)
@@ -325,6 +330,9 @@ final class HotwordDetectionConnection {
                        if (result != null) {
                            Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result)
                                    + " bits from hotword trusted process");
                            if (mDebugHotwordLogging) {
                                Slog.i(TAG, "Egressed detected result: " + result);
                            }
                        }
                    } else {
                        Slog.i(TAG, "Hotword detection has already completed");
@@ -415,6 +423,9 @@ final class HotwordDetectionConnection {
                        if (result != null) {
                            Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result)
                                    + " bits from hotword trusted process");
                            if (mDebugHotwordLogging) {
                                Slog.i(TAG, "Egressed detected result: " + result);
                            }
                        }
                    } else {
                        Slog.i(TAG, "Ignored hotword detected since trigger has been handled");
@@ -429,6 +440,9 @@ final class HotwordDetectionConnection {
                    if (mValidatingDspTrigger) {
                        mValidatingDspTrigger = false;
                        externalCallback.onRejected(result);
                        if (mDebugHotwordLogging && result != null) {
                            Slog.i(TAG, "Egressed rejected result: " + result);
                        }
                    } else {
                        Slog.i(TAG, "Ignored hotword rejected since trigger has been handled");
                    }
@@ -471,6 +485,9 @@ final class HotwordDetectionConnection {
                    if (result != null) {
                        Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result)
                                + " bits from hotword trusted process");
                        if (mDebugHotwordLogging) {
                            Slog.i(TAG, "Egressed detected result: " + result);
                        }
                    }
                }
            }
@@ -487,6 +504,9 @@ final class HotwordDetectionConnection {
                    }
                    mValidatingDspTrigger = false;
                    externalCallback.onRejected(result);
                    if (mDebugHotwordLogging && result != null) {
                        Slog.i(TAG, "Egressed rejected result: " + result);
                    }
                }
            }
        };
@@ -509,6 +529,29 @@ final class HotwordDetectionConnection {
        }
    }

    void setDebugHotwordLoggingLocked(boolean logging) {
        Slog.v(TAG, "setDebugHotwordLoggingLocked: " + logging);
        clearDebugHotwordLoggingTimeoutLocked();
        mDebugHotwordLogging = logging;

        if (logging) {
            // Reset mDebugHotwordLogging to false after one hour
            mDebugHotwordLoggingTimeoutFuture = mScheduledExecutorService.schedule(() -> {
                Slog.v(TAG, "Timeout to reset mDebugHotwordLogging to false");
                synchronized (mLock) {
                    mDebugHotwordLogging = false;
                }
            }, RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
        }
    }

    private void clearDebugHotwordLoggingTimeoutLocked() {
        if (mDebugHotwordLoggingTimeoutFuture != null) {
            mDebugHotwordLoggingTimeoutFuture.cancel(/* mayInterruptIfRunning= */true);
            mDebugHotwordLoggingTimeoutFuture = null;
        }
    }

    private void restartProcessLocked() {
        Slog.v(TAG, "Restarting hotword detection process");
        ServiceConnection oldConnection = mRemoteHotwordDetectionService;
@@ -682,6 +725,9 @@ final class HotwordDetectionConnection {
                                bestEffortClose(serviceAudioSource);
                                bestEffortClose(audioSource);

                                if (mDebugHotwordLogging && result != null) {
                                    Slog.i(TAG, "Egressed rejected result: " + result);
                                }
                                // TODO: Propagate the HotwordRejectedResult.
                            }

@@ -696,6 +742,9 @@ final class HotwordDetectionConnection {
                                if (triggerResult != null) {
                                    Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(
                                            triggerResult) + " bits from hotword trusted process");
                                    if (mDebugHotwordLogging) {
                                        Slog.i(TAG, "Egressed detected result: " + triggerResult);
                                    }
                                }
                                // TODO: Add a delay before closing.
                                bestEffortClose(audioSource);
+11 −0
Original line number Diff line number Diff line
@@ -832,6 +832,17 @@ public class VoiceInteractionManagerService extends SystemService {
            mImpl.forceRestartHotwordDetector();
        }

        // Called by Shell command
        void setDebugHotwordLogging(boolean logging) {
            synchronized (this) {
                if (mImpl == null) {
                    Slog.w(TAG, "setTemporaryLogging without running voice interaction service");
                    return;
                }
                mImpl.setDebugHotwordLoggingLocked(logging);
            }
        }

        @Override
        public void showSession(Bundle args, int flags) {
            synchronized (this) {
+8 −0
Original line number Diff line number Diff line
@@ -581,6 +581,14 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
        mHotwordDetectionConnection.forceRestart();
    }

    void setDebugHotwordLoggingLocked(boolean logging) {
        if (mHotwordDetectionConnection == null) {
            Slog.w(TAG, "Failed to set temporary debug logging: no hotword detection active");
            return;
        }
        mHotwordDetectionConnection.setDebugHotwordLoggingLocked(logging);
    }

    void resetHotwordDetectionConnectionLocked() {
        if (DEBUG) {
            Slog.d(TAG, "resetHotwordDetectionConnectionLocked");
+18 −0
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ final class VoiceInteractionManagerServiceShellCommand extends ShellCommand {
                return requestDisable(pw);
            case "restart-detection":
                return requestRestartDetection(pw);
            case "set-debug-hotword-logging":
                return setDebugHotwordLogging(pw);
            default:
                return handleDefaultCommands(cmd);
        }
@@ -76,9 +78,14 @@ final class VoiceInteractionManagerServiceShellCommand extends ShellCommand {
            pw.println("");
            pw.println("  disable [true|false]");
            pw.println("    Temporarily disable (when true) service");
            pw.println("");
            pw.println("  restart-detection");
            pw.println("    Force a restart of a hotword detection service");
            pw.println("");
            pw.println("  set-debug-hotword-logging [true|false]");
            pw.println("    Temporarily enable or disable debug logging for hotword result.");
            pw.println("    The debug logging will be reset after one hour from last enable.");
            pw.println("");
        }
    }

@@ -157,6 +164,17 @@ final class VoiceInteractionManagerServiceShellCommand extends ShellCommand {
        return 0;
    }

    private int setDebugHotwordLogging(PrintWriter pw) {
        boolean logging = Boolean.parseBoolean(getNextArgRequired());
        Slog.i(TAG, "setDebugHotwordLogging(): " + logging);
        try {
            mService.setDebugHotwordLogging(logging);
        } catch (Exception e) {
            return handleError(pw, "setDebugHotwordLogging()", e);
        }
        return 0;
    }

    private static int handleError(PrintWriter pw, String message, Exception e) {
        Slog.e(TAG,  "error calling " + message, e);
        pw.printf("Error calling %s: %s\n", message, e);