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

Commit 33109c19 authored by Ajay Gopi's avatar Ajay Gopi
Browse files

Expand HDS API to allow egressing training data

Change-Id: Ibde0c39ec1223c816d369a4f2e2793d295e00903
Test: atest --no-bazel-mode CtsVoiceInteractionTestCases:HotwordDetectionServiceBasicTest
Bug: 291599840
parent 44ff5531
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -315,6 +315,7 @@ package android {
    field @FlaggedApi("android.app.usage.report_usage_stats_permission") public static final String REPORT_USAGE_STATS = "android.permission.REPORT_USAGE_STATS";
    field @Deprecated public static final String REQUEST_NETWORK_SCORES = "android.permission.REQUEST_NETWORK_SCORES";
    field public static final String REQUEST_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE";
    field @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") public static final String RESET_HOTWORD_TRAINING_DATA_EGRESS_COUNT = "android.permission.RESET_HOTWORD_TRAINING_DATA_EGRESS_COUNT";
    field public static final String RESET_PASSWORD = "android.permission.RESET_PASSWORD";
    field public static final String RESTART_WIFI_SUBSYSTEM = "android.permission.RESTART_WIFI_SUBSYSTEM";
    field public static final String RESTORE_RUNTIME_PERMISSIONS = "android.permission.RESTORE_RUNTIME_PERMISSIONS";
@@ -12688,6 +12689,7 @@ package android.service.voice {
  public static final class HotwordDetectionService.Callback {
    method public void onDetected(@NonNull android.service.voice.HotwordDetectedResult);
    method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult);
    method @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") public void onTrainingData(@NonNull android.service.voice.HotwordTrainingData);
  }
  public final class HotwordDetectionServiceFailure implements android.os.Parcelable {
@@ -12703,6 +12705,8 @@ package android.service.voice {
    field public static final int ERROR_CODE_DETECT_TIMEOUT = 4; // 0x4
    field public static final int ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION = 5; // 0x5
    field public static final int ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE = 6; // 0x6
    field @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") public static final int ERROR_CODE_ON_TRAINING_DATA_EGRESS_LIMIT_EXCEEDED = 8; // 0x8
    field @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") public static final int ERROR_CODE_ON_TRAINING_DATA_SECURITY_EXCEPTION = 9; // 0x9
    field public static final int ERROR_CODE_REMOTE_EXCEPTION = 7; // 0x7
    field public static final int ERROR_CODE_UNKNOWN = 0; // 0x0
  }
@@ -12724,6 +12728,7 @@ package android.service.voice {
    method public void onRecognitionPaused();
    method public void onRecognitionResumed();
    method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult);
    method @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") public default void onTrainingData(@NonNull android.service.voice.HotwordTrainingData);
    method public default void onUnknownFailure(@NonNull String);
  }
+1 −0
Original line number Diff line number Diff line
@@ -3047,6 +3047,7 @@ package android.service.voice {
    method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION) public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetectorForTest(@NonNull String, @NonNull java.util.Locale, @NonNull android.hardware.soundtrigger.SoundTrigger.ModuleProperties, @NonNull java.util.concurrent.Executor, @NonNull android.service.voice.AlwaysOnHotwordDetector.Callback);
    method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION) public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetectorForTest(@NonNull String, @NonNull java.util.Locale, @Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory, @NonNull android.hardware.soundtrigger.SoundTrigger.ModuleProperties, @NonNull java.util.concurrent.Executor, @NonNull android.service.voice.AlwaysOnHotwordDetector.Callback);
    method @NonNull public final java.util.List<android.hardware.soundtrigger.SoundTrigger.ModuleProperties> listModuleProperties();
    method @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") @RequiresPermission(android.Manifest.permission.RESET_HOTWORD_TRAINING_DATA_EGRESS_COUNT) public final void resetHotwordTrainingDataEgressCountForTest();
    method public final void setTestModuleForAlwaysOnHotwordDetectorEnabled(boolean);
  }

+7 −0
Original line number Diff line number Diff line
@@ -263,5 +263,12 @@ abstract class AbstractDetector implements HotwordDetector {
                        result != null ? result : new HotwordRejectedResult.Builder().build());
            }));
        }

        @Override
        public void onTrainingData(HotwordTrainingData data) {
            Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
                mCallback.onTrainingData(data);
            }));
        }
    }
}
+14 −0
Original line number Diff line number Diff line
@@ -306,6 +306,7 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
    private static final int MSG_DETECTION_HOTWORD_DETECTION_SERVICE_FAILURE = 9;
    private static final int MSG_DETECTION_SOUND_TRIGGER_FAILURE = 10;
    private static final int MSG_DETECTION_UNKNOWN_FAILURE = 11;
    private static final int MSG_HOTWORD_TRAINING_DATA = 12;

    private final String mText;
    private final Locale mLocale;
@@ -1652,6 +1653,16 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
            Message.obtain(mHandler, MSG_HOTWORD_REJECTED, result).sendToTarget();
        }

        @Override
        public void onTrainingData(@NonNull HotwordTrainingData data) {
            if (DBG) {
                Slog.d(TAG, "onTrainingData(" + data + ")");
            } else {
                Slog.i(TAG, "onTrainingData");
            }
            Message.obtain(mHandler, MSG_HOTWORD_TRAINING_DATA, data).sendToTarget();
        }

        @Override
        public void onHotwordDetectionServiceFailure(
                HotwordDetectionServiceFailure hotwordDetectionServiceFailure) {
@@ -1783,6 +1794,9 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
                    case MSG_DETECTION_UNKNOWN_FAILURE:
                        mExternalCallback.onUnknownFailure((String) message.obj);
                        break;
                    case MSG_HOTWORD_TRAINING_DATA:
                        mExternalCallback.onTrainingData((HotwordTrainingData) message.obj);
                        break;
                    default:
                        super.handleMessage(message);
                }
+27 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.service.voice;
import static java.util.Objects.requireNonNull;

import android.annotation.DurationMillisLong;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -39,6 +40,7 @@ import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SharedMemory;
import android.service.voice.flags.Flags;
import android.speech.IRecognitionServiceManager;
import android.util.Log;
import android.view.contentcapture.ContentCaptureManager;
@@ -443,5 +445,30 @@ public abstract class HotwordDetectionService extends Service
                throw e.rethrowFromSystemServer();
            }
        }

        /**
         * Informs the {@link HotwordDetector} when there is training data.
         *
         * <p> A daily limit of 20 is enforced on training data events sent. Number events egressed
         * are tracked across UTC day (24-hour window) and count is reset at midnight
         * (UTC 00:00:00). To be informed of failures to egress training data due to limit being
         * reached, the associated hotword detector should listen for
         * {@link HotwordDetectionServiceFailure#ERROR_CODE_ON_TRAINING_DATA_EGRESS_LIMIT_EXCEEDED}
         * events in {@link HotwordDetector.Callback#onFailure(HotwordDetectionServiceFailure)}.
         *
         * @param data Training data determined by the service. This is provided to the
         *               {@link HotwordDetector}.
         */
        @FlaggedApi(Flags.FLAG_ALLOW_TRAINING_DATA_EGRESS_FROM_HDS)
        public void onTrainingData(@NonNull HotwordTrainingData data) {
            requireNonNull(data);
            try {
                Log.d(TAG, "onTrainingData");
                mRemoteCallback.onTrainingData(data);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }

    }
}
Loading