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

Commit 6ed6340e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "SoundTriggerJobService-steps" into pi-dev

* changes:
  Throttle number of sound trigger operations / day
  Add SoundTriggerDetectionService
  Expose SoundTriggerManager and SoundTrigger APIs
parents efcd6e1c 7e25b3d9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -462,6 +462,8 @@ java_library {
        "media/java/android/media/session/ISessionController.aidl",
        "media/java/android/media/session/ISessionControllerCallback.aidl",
        "media/java/android/media/session/ISessionManager.aidl",
        "media/java/android/media/soundtrigger/ISoundTriggerDetectionService.aidl",
        "media/java/android/media/soundtrigger/ISoundTriggerDetectionServiceClient.aidl",
        "media/java/android/media/tv/ITvInputClient.aidl",
        "media/java/android/media/tv/ITvInputHardware.aidl",
        "media/java/android/media/tv/ITvInputHardwareCallback.aidl",
+28 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ package android {
    field public static final java.lang.String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
    field public static final java.lang.String BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE = "android.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE";
    field public static final java.lang.String BIND_SETTINGS_SUGGESTIONS_SERVICE = "android.permission.BIND_SETTINGS_SUGGESTIONS_SERVICE";
    field public static final java.lang.String BIND_SOUND_TRIGGER_DETECTION_SERVICE = "android.permission.BIND_SOUND_TRIGGER_DETECTION_SERVICE";
    field public static final java.lang.String BIND_TELEPHONY_DATA_SERVICE = "android.permission.BIND_TELEPHONY_DATA_SERVICE";
    field public static final java.lang.String BIND_TELEPHONY_NETWORK_SERVICE = "android.permission.BIND_TELEPHONY_NETWORK_SERVICE";
    field public static final java.lang.String BIND_TEXTCLASSIFIER_SERVICE = "android.permission.BIND_TEXTCLASSIFIER_SERVICE";
@@ -99,6 +100,7 @@ package android {
    field public static final java.lang.String MANAGE_CARRIER_OEM_UNLOCK_STATE = "android.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE";
    field public static final java.lang.String MANAGE_CA_CERTIFICATES = "android.permission.MANAGE_CA_CERTIFICATES";
    field public static final java.lang.String MANAGE_DEVICE_ADMINS = "android.permission.MANAGE_DEVICE_ADMINS";
    field public static final java.lang.String MANAGE_SOUND_TRIGGER = "android.permission.MANAGE_SOUND_TRIGGER";
    field public static final java.lang.String MANAGE_SUBSCRIPTION_PLANS = "android.permission.MANAGE_SUBSCRIPTION_PLANS";
    field public static final java.lang.String MANAGE_USB = "android.permission.MANAGE_USB";
    field public static final java.lang.String MANAGE_USERS = "android.permission.MANAGE_USERS";
@@ -2222,6 +2224,21 @@ package android.hardware.radio {

}

package android.hardware.soundtrigger {

  public class SoundTrigger {
    field public static final int STATUS_OK = 0; // 0x0
  }

  public static class SoundTrigger.RecognitionEvent {
    method public android.media.AudioFormat getCaptureFormat();
    method public int getCaptureSession();
    method public byte[] getData();
    method public boolean isCaptureAvailable();
  }

}

package android.hardware.usb {

  public class UsbDeviceConnection {
@@ -2737,6 +2754,16 @@ package android.media.session {

package android.media.soundtrigger {

  public abstract class SoundTriggerDetectionService extends android.app.Service {
    ctor public SoundTriggerDetectionService();
    method public void onConnected(java.util.UUID, android.os.Bundle);
    method public void onDisconnected(java.util.UUID, android.os.Bundle);
    method public void onError(java.util.UUID, android.os.Bundle, int, int);
    method public void onGenericRecognitionEvent(java.util.UUID, android.os.Bundle, int, android.hardware.soundtrigger.SoundTrigger.RecognitionEvent);
    method public abstract void onStopOperation(java.util.UUID, android.os.Bundle, int);
    method public final void operationFinished(java.util.UUID, int);
  }

  public final class SoundTriggerDetector {
    method public boolean startRecognition(int);
    method public boolean stopRecognition();
@@ -2761,6 +2788,7 @@ package android.media.soundtrigger {
  public final class SoundTriggerManager {
    method public android.media.soundtrigger.SoundTriggerDetector createSoundTriggerDetector(java.util.UUID, android.media.soundtrigger.SoundTriggerDetector.Callback, android.os.Handler);
    method public void deleteModel(java.util.UUID);
    method public int getDetectionServiceOperationsTimeout();
    method public android.media.soundtrigger.SoundTriggerManager.Model getModel(java.util.UUID);
    method public void updateModel(android.media.soundtrigger.SoundTriggerManager.Model);
  }
+9 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.DrawableRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringRes;
import android.annotation.UserIdInt;
import android.annotation.XmlRes;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -1031,18 +1032,24 @@ public class ApplicationPackageManager extends PackageManager {
    }

    @Override
    public ResolveInfo resolveService(Intent intent, int flags) {
    public ResolveInfo resolveServiceAsUser(Intent intent, @ResolveInfoFlags int flags,
            @UserIdInt int userId) {
        try {
            return mPM.resolveService(
                intent,
                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                flags,
                mContext.getUserId());
                userId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @Override
    public ResolveInfo resolveService(Intent intent, int flags) {
        return resolveServiceAsUser(intent, flags, mContext.getUserId());
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
+6 −0
Original line number Diff line number Diff line
@@ -4182,6 +4182,12 @@ public abstract class PackageManager {
     */
    public abstract ResolveInfo resolveService(Intent intent, @ResolveInfoFlags int flags);

    /**
     * @hide
     */
    public abstract ResolveInfo resolveServiceAsUser(Intent intent, @ResolveInfoFlags int flags,
            @UserIdInt int userId);

    /**
     * Retrieve all services that can match the given intent.
     *
+195 −32
Original line number Diff line number Diff line
@@ -16,6 +16,14 @@

package android.hardware.soundtrigger;

import static android.system.OsConstants.EINVAL;
import static android.system.OsConstants.ENODEV;
import static android.system.OsConstants.ENOSYS;
import static android.system.OsConstants.EPERM;
import static android.system.OsConstants.EPIPE;

import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.media.AudioFormat;
import android.os.Handler;
import android.os.Parcel;
@@ -25,22 +33,33 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.UUID;

import static android.system.OsConstants.*;

/**
 * The SoundTrigger class provides access via JNI to the native service managing
 * the sound trigger HAL.
 *
 * @hide
 */
@SystemApi
public class SoundTrigger {

    private SoundTrigger() {
    }

    /**
     * Status code used when the operation succeeded
     */
    public static final int STATUS_OK = 0;
    /** @hide */
    public static final int STATUS_ERROR = Integer.MIN_VALUE;
    /** @hide */
    public static final int STATUS_PERMISSION_DENIED = -EPERM;
    /** @hide */
    public static final int STATUS_NO_INIT = -ENODEV;
    /** @hide */
    public static final int STATUS_BAD_VALUE = -EINVAL;
    /** @hide */
    public static final int STATUS_DEAD_OBJECT = -EPIPE;
    /** @hide */
    public static final int STATUS_INVALID_OPERATION = -ENOSYS;

    /*****************************************************************************
@@ -48,6 +67,8 @@ public class SoundTrigger {
     * managed by the native sound trigger service. Each module has a unique
     * ID used to target any API call to this paricular module. Module
     * properties are returned by listModules() method.
     *
     * @hide
     ****************************************************************************/
    public static class ModuleProperties implements Parcelable {
        /** Unique module ID provided by the native service */
@@ -187,6 +208,8 @@ public class SoundTrigger {
     * implementation to detect a particular sound pattern.
     * A specialized version {@link KeyphraseSoundModel} is defined for key phrase
     * sound models.
     *
     * @hide
     ****************************************************************************/
    public static class SoundModel {
        /** Undefined sound model type */
@@ -261,6 +284,8 @@ public class SoundTrigger {
    /*****************************************************************************
     * A Keyphrase describes a key phrase that can be detected by a
     * {@link KeyphraseSoundModel}
     *
     * @hide
     ****************************************************************************/
    public static class Keyphrase implements Parcelable {
        /** Unique identifier for this keyphrase */
@@ -382,6 +407,8 @@ public class SoundTrigger {
     * A KeyphraseSoundModel is a specialized {@link SoundModel} for key phrases.
     * It contains data needed by the hardware to detect a certain number of key phrases
     * and the list of corresponding {@link Keyphrase} descriptors.
     *
     * @hide
     ****************************************************************************/
    public static class KeyphraseSoundModel extends SoundModel implements Parcelable {
        /** Key phrases in this sound model */
@@ -468,6 +495,8 @@ public class SoundTrigger {
    /*****************************************************************************
     * A GenericSoundModel is a specialized {@link SoundModel} for non-voice sound
     * patterns.
     *
     * @hide
     ****************************************************************************/
    public static class GenericSoundModel extends SoundModel implements Parcelable {

@@ -524,52 +553,115 @@ public class SoundTrigger {
    /**
     *  Modes for key phrase recognition
     */
    /** Simple recognition of the key phrase */

    /**
     * Simple recognition of the key phrase
     *
     * @hide
     */
    public static final int RECOGNITION_MODE_VOICE_TRIGGER = 0x1;
    /** Trigger only if one user is identified */
    /**
     * Trigger only if one user is identified
     *
     * @hide
     */
    public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 0x2;
    /** Trigger only if one user is authenticated */
    /**
     * Trigger only if one user is authenticated
     *
     * @hide
     */
    public static final int RECOGNITION_MODE_USER_AUTHENTICATION = 0x4;

    /**
     *  Status codes for {@link RecognitionEvent}
     */
    /** Recognition success */
    /**
     * Recognition success
     *
     * @hide
     */
    public static final int RECOGNITION_STATUS_SUCCESS = 0;
    /** Recognition aborted (e.g. capture preempted by anotehr use case */
    /**
     * Recognition aborted (e.g. capture preempted by anotehr use case
     *
     * @hide
     */
    public static final int RECOGNITION_STATUS_ABORT = 1;
    /** Recognition failure */
    /**
     * Recognition failure
     *
     * @hide
     */
    public static final int RECOGNITION_STATUS_FAILURE = 2;

    /**
     *  A RecognitionEvent is provided by the
     *  {@link StatusListener#onRecognition(RecognitionEvent)}
     *  {@code StatusListener#onRecognition(RecognitionEvent)}
     *  callback upon recognition success or failure.
     */
    public static class RecognitionEvent implements Parcelable {
        /** Recognition status e.g {@link #RECOGNITION_STATUS_SUCCESS} */
    public static class RecognitionEvent {
        /**
         * Recognition status e.g RECOGNITION_STATUS_SUCCESS
         *
         * @hide
         */
        public final int status;
        /** Sound Model corresponding to this event callback */
        /**
         *
         * Sound Model corresponding to this event callback
         *
         * @hide
         */
        public final int soundModelHandle;
        /** True if it is possible to capture audio from this utterance buffered by the hardware */
        /**
         * True if it is possible to capture audio from this utterance buffered by the hardware
         *
         * @hide
         */
        public final boolean captureAvailable;
        /** Audio session ID to be used when capturing the utterance with an AudioRecord
         * if captureAvailable() is true. */
        /**
         * Audio session ID to be used when capturing the utterance with an AudioRecord
         * if captureAvailable() is true.
         *
         * @hide
         */
        public final int captureSession;
        /** Delay in ms between end of model detection and start of audio available for capture.
         * A negative value is possible (e.g. if keyphrase is also available for capture) */
        /**
         * Delay in ms between end of model detection and start of audio available for capture.
         * A negative value is possible (e.g. if keyphrase is also available for capture)
         *
         * @hide
         */
        public final int captureDelayMs;
        /** Duration in ms of audio captured before the start of the trigger. 0 if none. */
        /**
         * Duration in ms of audio captured before the start of the trigger. 0 if none.
         *
         * @hide
         */
        public final int capturePreambleMs;
        /** True if  the trigger (key phrase capture is present in binary data */
        /**
         * True if  the trigger (key phrase capture is present in binary data
         *
         * @hide
         */
        public final boolean triggerInData;
        /** Audio format of either the trigger in event data or to use for capture of the
          * rest of the utterance */
        public AudioFormat captureFormat;
        /** Opaque data for use by system applications who know about voice engine internals,
         * typically during enrollment. */
        /**
         * Audio format of either the trigger in event data or to use for capture of the
         * rest of the utterance
         *
         * @hide
         */
        public final AudioFormat captureFormat;
        /**
         * Opaque data for use by system applications who know about voice engine internals,
         * typically during enrollment.
         *
         * @hide
         */
        public final byte[] data;

        /** @hide */
        public RecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
                int captureSession, int captureDelayMs, int capturePreambleMs,
                boolean triggerInData, AudioFormat captureFormat, byte[] data) {
@@ -584,6 +676,46 @@ public class SoundTrigger {
            this.data = data;
        }

        /**
         * Check if is possible to capture audio from this utterance buffered by the hardware.
         *
         * @return {@code true} iff a capturing is possible
         */
        public boolean isCaptureAvailable() {
            return captureAvailable;
        }

        /**
         * Get the audio format of either the trigger in event data or to use for capture of the
         * rest of the utterance
         *
         * @return the audio format
         */
        @Nullable public AudioFormat getCaptureFormat() {
            return captureFormat;
        }

        /**
         * Get Audio session ID to be used when capturing the utterance with an {@link AudioRecord}
         * if {@link #isCaptureAvailable()} is true.
         *
         * @return The id of the capture session
         */
        public int getCaptureSession() {
            return captureSession;
        }

        /**
         * Get the opaque data for use by system applications who know about voice engine
         * internals, typically during enrollment.
         *
         * @return The data of the event
         */
        public byte[] getData() {
            return data;
        }

        /** @hide */
        public static final Parcelable.Creator<RecognitionEvent> CREATOR
                = new Parcelable.Creator<RecognitionEvent>() {
            public RecognitionEvent createFromParcel(Parcel in) {
@@ -595,6 +727,7 @@ public class SoundTrigger {
            }
        };

        /** @hide */
        protected static RecognitionEvent fromParcel(Parcel in) {
            int status = in.readInt();
            int soundModelHandle = in.readInt();
@@ -619,12 +752,12 @@ public class SoundTrigger {
                    captureDelayMs, capturePreambleMs, triggerInData, captureFormat, data);
        }

        @Override
        /** @hide */
        public int describeContents() {
            return 0;
        }

        @Override
        /** @hide */
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(status);
            dest.writeInt(soundModelHandle);
@@ -726,6 +859,8 @@ public class SoundTrigger {
     *  A RecognitionConfig is provided to
     *  {@link SoundTriggerModule#startRecognition(int, RecognitionConfig)} to configure the
     *  recognition request.
     *
     *  @hide
     */
    public static class RecognitionConfig implements Parcelable {
        /** True if the DSP should capture the trigger sound and make it available for further
@@ -744,7 +879,7 @@ public class SoundTrigger {
        public final byte[] data;

        public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
                KeyphraseRecognitionExtra keyphrases[], byte[] data) {
                KeyphraseRecognitionExtra[] keyphrases, byte[] data) {
            this.captureRequested = captureRequested;
            this.allowMultipleTriggers = allowMultipleTriggers;
            this.keyphrases = keyphrases;
@@ -799,6 +934,8 @@ public class SoundTrigger {
     * When used in a {@link RecognitionConfig} it indicates the minimum confidence level that
     * should trigger a recognition.
     * - The user ID is derived from the system ID {@link android.os.UserHandle#getIdentifier()}.
     *
     * @hide
     */
    public static class ConfidenceLevel implements Parcelable {
        public final int userId;
@@ -872,6 +1009,8 @@ public class SoundTrigger {
    /**
     *  Additional data conveyed by a {@link KeyphraseRecognitionEvent}
     *  for a key phrase detection.
     *
     * @hide
     */
    public static class KeyphraseRecognitionExtra implements Parcelable {
        /** The keyphrase ID */
@@ -970,8 +1109,10 @@ public class SoundTrigger {

    /**
     *  Specialized {@link RecognitionEvent} for a key phrase detection.
     *
     *  @hide
     */
    public static class KeyphraseRecognitionEvent extends RecognitionEvent {
    public static class KeyphraseRecognitionEvent extends RecognitionEvent implements Parcelable {
        /** Indicates if the key phrase is present in the buffered audio available for capture */
        public final KeyphraseRecognitionExtra[] keyphraseExtras;

@@ -1091,8 +1232,10 @@ public class SoundTrigger {
    /**
     * Sub-class of RecognitionEvent specifically for sound-trigger based sound
     * models(non-keyphrase). Currently does not contain any additional fields.
     *
     * @hide
     */
    public static class GenericRecognitionEvent extends RecognitionEvent {
    public static class GenericRecognitionEvent extends RecognitionEvent implements Parcelable {
        public GenericRecognitionEvent(int status, int soundModelHandle,
                boolean captureAvailable, int captureSession, int captureDelayMs,
                int capturePreambleMs, boolean triggerInData, AudioFormat captureFormat,
@@ -1140,13 +1283,19 @@ public class SoundTrigger {
    /**
     *  Status codes for {@link SoundModelEvent}
     */
    /** Sound Model was updated */
    /**
     * Sound Model was updated
     *
     * @hide
     */
    public static final int SOUNDMODEL_STATUS_UPDATED = 0;

    /**
     *  A SoundModelEvent is provided by the
     *  {@link StatusListener#onSoundModelUpdate(SoundModelEvent)}
     *  callback when a sound model has been updated by the implementation
     *
     *  @hide
     */
    public static class SoundModelEvent implements Parcelable {
        /** Status e.g {@link #SOUNDMODEL_STATUS_UPDATED} */
@@ -1231,9 +1380,17 @@ public class SoundTrigger {
     *  Native service state. {@link StatusListener#onServiceStateChange(int)}
     */
    // Keep in sync with system/core/include/system/sound_trigger.h
    /** Sound trigger service is enabled */
    /**
     * Sound trigger service is enabled
     *
     * @hide
     */
    public static final int SERVICE_STATE_ENABLED = 0;
    /** Sound trigger service is disabled */
    /**
     * Sound trigger service is disabled
     *
     * @hide
     */
    public static final int SERVICE_STATE_DISABLED = 1;

    /**
@@ -1245,6 +1402,8 @@ public class SoundTrigger {
     *         - {@link #STATUS_NO_INIT} if the native service cannot be reached
     *         - {@link #STATUS_BAD_VALUE} if modules is null
     *         - {@link #STATUS_DEAD_OBJECT} if the binder transaction to the native service fails
     *
     * @hide
     */
    public static native int listModules(ArrayList <ModuleProperties> modules);

@@ -1256,6 +1415,8 @@ public class SoundTrigger {
     * @param handler the Handler that will receive the callabcks. Can be null if default handler
     *                is OK.
     * @return a valid sound module in case of success or null in case of error.
     *
     * @hide
     */
    public static SoundTriggerModule attachModule(int moduleId,
                                                  StatusListener listener,
@@ -1270,6 +1431,8 @@ public class SoundTrigger {
    /**
     * Interface provided by the client application when attaching to a {@link SoundTriggerModule}
     * to received recognition and error notifications.
     *
     * @hide
     */
    public static interface StatusListener {
        /**
Loading