• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 com.android.cts.voiceinteraction;
18 
19 import static java.lang.annotation.RetentionPolicy.SOURCE;
20 
21 import android.os.PersistableBundle;
22 import android.os.SharedMemory;
23 import android.service.voice.AlwaysOnHotwordDetector;
24 import android.service.voice.HotwordDetectedResult;
25 import android.service.voice.HotwordDetectionService;
26 import android.util.Log;
27 
28 import androidx.annotation.StringDef;
29 
30 import java.lang.annotation.Retention;
31 import java.util.function.IntConsumer;
32 
33 /**
34  * This {@link HotwordDetectionService} implementation is intended to have controllable behavior
35  * through the {@link #onUpdateState} API.
36  *
37  * All controllable behaviors are under the {@link ServiceControlApis} definition.
38  */
39 public class ControllableHotwordDetectionService extends HotwordDetectionService {
40     private static final String TAG = ControllableHotwordDetectionService.class.getSimpleName();
41 
42     /**
43      * Bundle keys for {@link #onUpdateState} which have special meaning to control the behavior
44      * of the service.
45      */
46     @Retention(SOURCE)
47     @StringDef({
48             KEY_FORCE_HOTWORD_RESULT_PHRASE_ID,
49     })
50     public @interface ServiceControlApis {
51     }
52 
53     // Key used to force the returned phrase ID for all onDetected events
54     public static final String KEY_FORCE_HOTWORD_RESULT_PHRASE_ID =
55             "FORCE_HOTWORD_RESULT_PHRASE_ID";
56 
57     // Current onUpdateState Options
58     private int mHotwordResultPhraseId = 0;
59 
60     @Override
onDetect(AlwaysOnHotwordDetector.EventPayload eventPayload, long timeoutMillis, Callback callback)61     public void onDetect(AlwaysOnHotwordDetector.EventPayload eventPayload, long timeoutMillis,
62             Callback callback) {
63         Log.d(TAG, "onDetect: eventPayload=" + eventPayload
64                 + ", timeoutMillis=" + timeoutMillis
65                 + ", callback=" + callback);
66         callback.onDetected(new HotwordDetectedResult.Builder()
67                 .setHotwordPhraseId(mHotwordResultPhraseId)
68                 .build());
69     }
70 
71     @Override
onUpdateState(PersistableBundle options, SharedMemory sharedMemory, long callbackTimeoutMillis, IntConsumer statusCallback)72     public void onUpdateState(PersistableBundle options, SharedMemory sharedMemory,
73             long callbackTimeoutMillis, IntConsumer statusCallback) {
74         Log.d(TAG, "onUpdateState: options=" + options
75                 + ", sharedMemory=" + sharedMemory
76                 + ", callbackTimeoutMillis=" + callbackTimeoutMillis
77                 + ", statusCallback=" + statusCallback);
78         mHotwordResultPhraseId = options.getInt(KEY_FORCE_HOTWORD_RESULT_PHRASE_ID);
79         if (statusCallback != null) {
80             statusCallback.accept(HotwordDetectionService.INITIALIZATION_STATUS_SUCCESS);
81         }
82     }
83 }
84