blob: ad02d2b77a995e48424712b83f0d53c85b2ac4a0 [file] [log] [blame]
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -08001/*
2 * Copyright (C) 2014 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
17package android.hardware.soundtrigger;
18
Ryan Bavettac92bbd72016-03-06 20:50:10 -080019import static org.mockito.Matchers.any;
20import static org.mockito.Matchers.eq;
21import static org.mockito.Mockito.spy;
22import static org.mockito.Mockito.timeout;
23import static org.mockito.Mockito.verify;
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -080024
25import android.content.Context;
Ryan Bavettac92bbd72016-03-06 20:50:10 -080026import android.hardware.soundtrigger.SoundTrigger.GenericRecognitionEvent;
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -080027import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
Ryan Bavettac92bbd72016-03-06 20:50:10 -080028import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionEvent;
29import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -080030import android.media.soundtrigger.SoundTriggerManager;
31import android.os.ParcelUuid;
32import android.os.ServiceManager;
33import android.test.AndroidTestCase;
Ryan Bavettac92bbd72016-03-06 20:50:10 -080034import android.test.suitebuilder.annotation.LargeTest;
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -080035import android.test.suitebuilder.annotation.SmallTest;
36
37import com.android.internal.app.ISoundTriggerService;
38
Ryan Bavettac92bbd72016-03-06 20:50:10 -080039import java.io.DataOutputStream;
40import java.net.InetAddress;
41import java.net.Socket;
42import java.util.ArrayList;
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -080043import java.util.Random;
44import java.util.UUID;
45
Ryan Bavettac92bbd72016-03-06 20:50:10 -080046import org.mockito.MockitoAnnotations;
47
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -080048public class GenericSoundModelTest extends AndroidTestCase {
Ryan Bavettac92bbd72016-03-06 20:50:10 -080049 static final int MSG_DETECTION_ERROR = -1;
50 static final int MSG_DETECTION_RESUME = 0;
51 static final int MSG_DETECTION_PAUSE = 1;
52 static final int MSG_KEYPHRASE_TRIGGER = 2;
53 static final int MSG_GENERIC_TRIGGER = 4;
54
55 private Random random = new Random();
56 private ArrayList<UUID> loadedModelUuids;
57 private ISoundTriggerService soundTriggerService;
58 private SoundTriggerManager soundTriggerManager;
59
60 @Override
61 public void setUp() throws Exception {
62 super.setUp();
63 MockitoAnnotations.initMocks(this);
64
65 Context context = getContext();
66 soundTriggerService = ISoundTriggerService.Stub.asInterface(
67 ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE));
68 soundTriggerManager = (SoundTriggerManager) context.getSystemService(
69 Context.SOUND_TRIGGER_SERVICE);
70
71 loadedModelUuids = new ArrayList<UUID>();
72 }
73
74 @Override
75 public void tearDown() throws Exception {
76 for (UUID modelUuid : loadedModelUuids) {
77 soundTriggerService.deleteSoundModel(new ParcelUuid(modelUuid));
78 }
79 super.tearDown();
80 }
81
82 GenericSoundModel new_sound_model() {
83 // Create sound model
84 byte[] data = new byte[1024];
85 random.nextBytes(data);
86 UUID modelUuid = UUID.randomUUID();
87 UUID mVendorUuid = UUID.randomUUID();
88 return new GenericSoundModel(modelUuid, mVendorUuid, data);
89 }
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -080090
91 @SmallTest
92 public void testUpdateGenericSoundModel() throws Exception {
Ryan Bavettac92bbd72016-03-06 20:50:10 -080093 GenericSoundModel model = new_sound_model();
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -080094
Ryan Bavettac92bbd72016-03-06 20:50:10 -080095 // Update sound model
96 soundTriggerService.updateSoundModel(model);
97 loadedModelUuids.add(model.uuid);
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -080098
Ryan Bavettac92bbd72016-03-06 20:50:10 -080099 // Confirm it was updated
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -0800100 GenericSoundModel returnedModel =
Ryan Bavettac92bbd72016-03-06 20:50:10 -0800101 soundTriggerService.getSoundModel(new ParcelUuid(model.uuid));
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -0800102 assertEquals(model, returnedModel);
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -0800103 }
104
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -0800105 @SmallTest
106 public void testDeleteGenericSoundModel() throws Exception {
Ryan Bavettac92bbd72016-03-06 20:50:10 -0800107 GenericSoundModel model = new_sound_model();
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -0800108
Ryan Bavettac92bbd72016-03-06 20:50:10 -0800109 // Update sound model
110 soundTriggerService.updateSoundModel(model);
111 loadedModelUuids.add(model.uuid);
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -0800112
Ryan Bavettac92bbd72016-03-06 20:50:10 -0800113 // Delete sound model
114 soundTriggerService.deleteSoundModel(new ParcelUuid(model.uuid));
115 loadedModelUuids.remove(model.uuid);
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -0800116
Ryan Bavettac92bbd72016-03-06 20:50:10 -0800117 // Confirm it was deleted
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -0800118 GenericSoundModel returnedModel =
Ryan Bavettac92bbd72016-03-06 20:50:10 -0800119 soundTriggerService.getSoundModel(new ParcelUuid(model.uuid));
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -0800120 assertEquals(null, returnedModel);
121 }
Ryan Bavettac92bbd72016-03-06 20:50:10 -0800122
123 @LargeTest
124 public void testStartStopGenericSoundModel() throws Exception {
125 GenericSoundModel model = new_sound_model();
126
127 boolean captureTriggerAudio = true;
128 boolean allowMultipleTriggers = true;
129 RecognitionConfig config = new RecognitionConfig(captureTriggerAudio, allowMultipleTriggers,
130 null, null);
131 TestRecognitionStatusCallback spyCallback = spy(new TestRecognitionStatusCallback());
132
133 // Update and start sound model recognition
134 soundTriggerService.updateSoundModel(model);
135 loadedModelUuids.add(model.uuid);
136 int r = soundTriggerService.startRecognition(new ParcelUuid(model.uuid), spyCallback,
137 config);
138 assertEquals("Could Not Start Recognition with code: " + r,
139 android.hardware.soundtrigger.SoundTrigger.STATUS_OK, r);
140
141 // Stop recognition
142 r = soundTriggerService.stopRecognition(new ParcelUuid(model.uuid), spyCallback);
143 assertEquals("Could Not Stop Recognition with code: " + r,
144 android.hardware.soundtrigger.SoundTrigger.STATUS_OK, r);
145 }
146
147 @LargeTest
148 public void testTriggerGenericSoundModel() throws Exception {
149 GenericSoundModel model = new_sound_model();
150
151 boolean captureTriggerAudio = true;
152 boolean allowMultipleTriggers = true;
153 RecognitionConfig config = new RecognitionConfig(captureTriggerAudio, allowMultipleTriggers,
154 null, null);
155 TestRecognitionStatusCallback spyCallback = spy(new TestRecognitionStatusCallback());
156
157 // Update and start sound model
158 soundTriggerService.updateSoundModel(model);
159 loadedModelUuids.add(model.uuid);
160 soundTriggerService.startRecognition(new ParcelUuid(model.uuid), spyCallback, config);
161
162 // Send trigger to stub HAL
163 Socket socket = new Socket(InetAddress.getLocalHost(), 14035);
164 DataOutputStream out = new DataOutputStream(socket.getOutputStream());
165 out.writeBytes("trig " + model.uuid.toString() + "\r\n");
166 out.flush();
167 socket.close();
168
169 // Verify trigger was received
170 verify(spyCallback, timeout(100)).onGenericSoundTriggerDetected(any());
171 }
172
173
174 public class TestRecognitionStatusCallback extends IRecognitionStatusCallback.Stub {
175 @Override
176 public void onGenericSoundTriggerDetected(GenericRecognitionEvent recognitionEvent) {
177 }
178
179 @Override
180 public void onKeyphraseDetected(KeyphraseRecognitionEvent recognitionEvent) {
181 }
182
183 @Override
184 public void onError(int status) {
185 }
186
187 @Override
188 public void onRecognitionPaused() {
189 }
190
191 @Override
192 public void onRecognitionResumed() {
193 }
194 }
Ryan Bavettafc3ad3e2016-03-03 21:47:35 -0800195}