1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.service.voice;
18 
19 import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD;
20 import static android.Manifest.permission.RECORD_AUDIO;
21 
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.annotation.RequiresPermission;
25 import android.annotation.SystemApi;
26 import android.media.AudioFormat;
27 import android.os.ParcelFileDescriptor;
28 import android.os.PersistableBundle;
29 import android.os.SharedMemory;
30 
31 /**
32  * Basic functionality for hotword detectors.
33  *
34  * @hide
35  */
36 @SystemApi
37 public interface HotwordDetector {
38 
39     /**
40      * Starts hotword recognition.
41      * <p>
42      * On calling this, the system streams audio from the device microphone to this application's
43      * {@link HotwordDetectionService}. Audio is streamed until {@link #stopRecognition()} is
44      * called.
45      * <p>
46      * On detection of a hotword,
47      * {@link AlwaysOnHotwordDetector.Callback#onDetected(AlwaysOnHotwordDetector.EventPayload)}
48      * is called on the callback provided when creating this {@link HotwordDetector}.
49      * <p>
50      * There is a noticeable impact on battery while recognition is active, so make sure to call
51      * {@link #stopRecognition()} when detection isn't needed.
52      * <p>
53      * Calling this again while recognition is active does nothing.
54      *
55      * @return true if the request to start recognition succeeded
56      */
57     @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
startRecognition()58     boolean startRecognition();
59 
60     /**
61      * Stops hotword recognition.
62      *
63      * @return true if the request to stop recognition succeeded
64      */
stopRecognition()65     boolean stopRecognition();
66 
67     /**
68      * Starts hotword recognition on audio coming from an external connected microphone.
69      * <p>
70      * {@link #stopRecognition()} must be called before {@code audioStream} is closed.
71      *
72      * @param audioStream stream containing the audio bytes to run detection on
73      * @param audioFormat format of the encoded audio
74      * @param options options supporting detection, such as configuration specific to the
75      *         source of the audio. This will be provided to the {@link HotwordDetectionService}.
76      *         PersistableBundle does not allow any remotable objects or other contents that can be
77      *         used to communicate with other processes.
78      * @return true if the request to start recognition succeeded
79      */
startRecognition( @onNull ParcelFileDescriptor audioStream, @NonNull AudioFormat audioFormat, @Nullable PersistableBundle options)80     boolean startRecognition(
81             @NonNull ParcelFileDescriptor audioStream,
82             @NonNull AudioFormat audioFormat,
83             @Nullable PersistableBundle options);
84 
85     /**
86      * Set configuration and pass read-only data to hotword detection service.
87      *
88      * @param options Application configuration data to provide to the
89      * {@link HotwordDetectionService}. PersistableBundle does not allow any remotable objects or
90      * other contents that can be used to communicate with other processes.
91      * @param sharedMemory The unrestricted data blob to provide to the
92      * {@link HotwordDetectionService}. Use this to provide the hotword models data or other
93      * such data to the trusted process.
94      *
95      * @throws IllegalStateException if this HotwordDetector wasn't specified to use a
96      * {@link HotwordDetectionService} when it was created.
97      */
updateState(@ullable PersistableBundle options, @Nullable SharedMemory sharedMemory)98     void updateState(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory);
99 
100     /**
101      * The callback to notify of detection events.
102      */
103     interface Callback {
104 
105         /**
106          * Called when the keyphrase is spoken.
107          *
108          * @param eventPayload Payload data for the detection event.
109          */
110         // TODO: Consider creating a new EventPayload that the AOHD one subclasses.
onDetected(@onNull AlwaysOnHotwordDetector.EventPayload eventPayload)111         void onDetected(@NonNull AlwaysOnHotwordDetector.EventPayload eventPayload);
112 
113         /**
114          * Called when the detection fails due to an error.
115          */
onError()116         void onError();
117 
118         /**
119          * Called when the recognition is paused temporarily for some reason.
120          * This is an informational callback, and the clients shouldn't be doing anything here
121          * except showing an indication on their UI if they have to.
122          */
onRecognitionPaused()123         void onRecognitionPaused();
124 
125         /**
126          * Called when the recognition is resumed after it was temporarily paused.
127          * This is an informational callback, and the clients shouldn't be doing anything here
128          * except showing an indication on their UI if they have to.
129          */
onRecognitionResumed()130         void onRecognitionResumed();
131 
132         /**
133          * Called when the {@link HotwordDetectionService second stage detection} did not detect the
134          * keyphrase.
135          *
136          * @param result Info about the second stage detection result, provided by the
137          *         {@link HotwordDetectionService}.
138          */
onRejected(@onNull HotwordRejectedResult result)139         void onRejected(@NonNull HotwordRejectedResult result);
140 
141         /**
142          * Called when the {@link HotwordDetectionService} is created by the system and given a
143          * short amount of time to report it's initialization state.
144          *
145          * @param status Info about initialization state of {@link HotwordDetectionService}; the
146          * allowed values are {@link HotwordDetectionService#INITIALIZATION_STATUS_SUCCESS},
147          * 1<->{@link HotwordDetectionService#getMaxCustomInitializationStatus()},
148          * {@link HotwordDetectionService#INITIALIZATION_STATUS_UNKNOWN}.
149          */
onHotwordDetectionServiceInitialized(int status)150         void onHotwordDetectionServiceInitialized(int status);
151 
152         /**
153          * Called with the {@link HotwordDetectionService} is restarted.
154          *
155          * Clients are expected to call {@link HotwordDetector#updateState} to share the state with
156          * the newly created service.
157          */
onHotwordDetectionServiceRestarted()158         void onHotwordDetectionServiceRestarted();
159     }
160 }
161