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.attributionsource.cts.blamed2
18 
19 import android.content.ContextParams
20 import android.content.Intent
21 import android.media.AudioFormat
22 import android.media.AudioRecord
23 import android.media.AudioRecord.Builder
24 import android.media.MediaRecorder
25 import android.speech.RecognitionService
26 
27 class MyRecognitionService : RecognitionService() {
28     var recorder: AudioRecord? = null
29         get() = field
30         set(recorder) { field = recorder }
31 
onStartListeningnull32     override fun onStartListening(intent: Intent, callback: Callback) {
33         when (intent.extras?.get(OPERATION)!!) {
34             OPERATION_MIC_RECO_WITH_ATTRIBUTION -> {
35                 performOperationMicRecoWithAttribution(callback)
36                 return
37             }
38             OPERATION_INJECT_RECO_WITHOUT_ATTRIBUTION -> {
39                 performOperationInjectRecoWithoutAttribution(callback)
40                 return
41             }
42         }
43     }
44 
onStopListeningnull45     override fun onStopListening(callback: Callback) {}
46 
onCancelnull47     override fun onCancel(callback: Callback) {
48         val finalRecorder = recorder
49         if (finalRecorder != null) {
50             finalRecorder.stop()
51         }
52         mainExecutor.execute({
53             callback.bufferReceived(ByteArray(0))
54         })
55     }
56 
performOperationMicRecoWithAttributionnull57     fun performOperationMicRecoWithAttribution(callback: Callback) {
58         val attributionContext = createContext(ContextParams.Builder()
59                 .setNextAttributionSource(callback.callingAttributionSource)
60                 .build())
61 
62         // Setup a recorder
63         val localRecorder = Builder()
64                 .setContext(attributionContext)
65                 .setAudioSource(MediaRecorder.AudioSource.MIC)
66                 .setBufferSizeInBytes(
67                         AudioRecord.getMinBufferSize(8000,
68                                 AudioFormat.CHANNEL_IN_MONO,
69                                 AudioFormat.ENCODING_PCM_16BIT) * 10)
70                 .setAudioFormat(AudioFormat.Builder()
71                         .setSampleRate(8000)
72                         .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
73                         .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
74                         .build())
75                 .build()
76 
77         // Start recognition
78         localRecorder.startRecording()
79 
80         // Pretend we do something...
81         callback.bufferReceived(ByteArray(0))
82 
83         recorder = localRecorder
84     }
85 
performOperationInjectRecoWithoutAttributionnull86     fun performOperationInjectRecoWithoutAttribution(callback: Callback) {
87         mainExecutor.execute({
88             callback.bufferReceived(ByteArray(0))
89         })
90     }
91 
92     companion object {
93         val OPERATION = "operation"
94         val OPERATION_MIC_RECO_WITH_ATTRIBUTION = "operation:mic_reco_with_attribution"
95         val OPERATION_INJECT_RECO_WITHOUT_ATTRIBUTION = "operation:inject_reco_without_attribution"
96     }
97 }
98