1 /* 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 17 package com.android.server.soundtrigger; 18 19 import android.hardware.soundtrigger.SoundTrigger.ConfidenceLevel; 20 import android.hardware.soundtrigger.SoundTrigger.Keyphrase; 21 import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionEvent; 22 import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra; 23 import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel; 24 import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent; 25 import android.hardware.soundtrigger.SoundTrigger; 26 import android.media.AudioFormat; 27 import android.os.Parcel; 28 import android.test.InstrumentationTestCase; 29 import android.test.suitebuilder.annotation.LargeTest; 30 import android.test.suitebuilder.annotation.SmallTest; 31 import android.os.Binder; 32 33 import java.util.Arrays; 34 import java.util.Locale; 35 import java.util.Random; 36 import java.util.UUID; 37 38 public class SoundTriggerTest extends InstrumentationTestCase { 39 private Random mRandom = new Random(); 40 41 @SmallTest testKeyphraseParcelUnparcel_noUsers()42 public void testKeyphraseParcelUnparcel_noUsers() throws Exception { 43 Keyphrase keyphrase = new Keyphrase(1, 0, 44 Locale.forLanguageTag("en-US"), "hello", null); 45 46 // Write to a parcel 47 Parcel parcel = Parcel.obtain(); 48 keyphrase.writeToParcel(parcel, 0); 49 50 // Read from it 51 parcel.setDataPosition(0); 52 Keyphrase unparceled = Keyphrase.CREATOR.createFromParcel(parcel); 53 54 // Verify that they are the same 55 assertEquals(keyphrase, unparceled); 56 } 57 58 @SmallTest testKeyphraseParcelUnparcel_zeroUsers()59 public void testKeyphraseParcelUnparcel_zeroUsers() throws Exception { 60 Keyphrase keyphrase = new Keyphrase(1, 0, 61 Locale.forLanguageTag("en-US"), "hello", new int[0]); 62 63 // Write to a parcel 64 Parcel parcel = Parcel.obtain(); 65 keyphrase.writeToParcel(parcel, 0); 66 67 // Read from it 68 parcel.setDataPosition(0); 69 Keyphrase unparceled = Keyphrase.CREATOR.createFromParcel(parcel); 70 71 // Verify that they are the same 72 assertEquals(keyphrase.getId(), unparceled.getId()); 73 assertTrue(Arrays.equals(keyphrase.getUsers(), unparceled.getUsers())); 74 assertEquals(keyphrase.getLocale(), unparceled.getLocale()); 75 assertEquals(keyphrase.getText(), unparceled.getText()); 76 } 77 78 @SmallTest testKeyphraseParcelUnparcel_pos()79 public void testKeyphraseParcelUnparcel_pos() throws Exception { 80 Keyphrase keyphrase = new Keyphrase(1, 0, 81 Locale.forLanguageTag("en-US"), "hello", new int[] {1, 2, 3, 4, 5}); 82 83 // Write to a parcel 84 Parcel parcel = Parcel.obtain(); 85 keyphrase.writeToParcel(parcel, 0); 86 87 // Read from it 88 parcel.setDataPosition(0); 89 Keyphrase unparceled = Keyphrase.CREATOR.createFromParcel(parcel); 90 91 // Verify that they are the same 92 assertEquals(keyphrase.getId(), unparceled.getId()); 93 assertTrue(Arrays.equals(keyphrase.getUsers(), unparceled.getUsers())); 94 assertEquals(keyphrase.getLocale(), unparceled.getLocale()); 95 assertEquals(keyphrase.getText(), unparceled.getText()); 96 } 97 98 @SmallTest testKeyphraseSoundModelParcelUnparcel_noData()99 public void testKeyphraseSoundModelParcelUnparcel_noData() throws Exception { 100 Keyphrase[] keyphrases = new Keyphrase[2]; 101 keyphrases[0] = new Keyphrase(1, 0, Locale.forLanguageTag("en-US"), 102 "hello", new int[] {0}); 103 keyphrases[1] = new Keyphrase(2, 0, Locale.forLanguageTag("fr-FR"), 104 "there", new int[] {1, 2}); 105 KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), UUID.randomUUID(), 106 null, keyphrases); 107 108 // Write to a parcel 109 Parcel parcel = Parcel.obtain(); 110 ksm.writeToParcel(parcel, 0); 111 112 // Read from it 113 parcel.setDataPosition(0); 114 KeyphraseSoundModel unparceled = KeyphraseSoundModel.CREATOR.createFromParcel(parcel); 115 116 // Verify that they are the same 117 assertEquals(ksm, unparceled); 118 } 119 120 @SmallTest testKeyphraseSoundModelParcelUnparcel_zeroData()121 public void testKeyphraseSoundModelParcelUnparcel_zeroData() throws Exception { 122 Keyphrase[] keyphrases = new Keyphrase[2]; 123 keyphrases[0] = new Keyphrase(1, 0, Locale.forLanguageTag("en-US"), 124 "hello", new int[] {0}); 125 keyphrases[1] = new Keyphrase(2, 0, Locale.forLanguageTag("fr-FR"), 126 "there", new int[] {1, 2}); 127 KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), UUID.randomUUID(), 128 new byte[0], keyphrases); 129 130 // Write to a parcel 131 Parcel parcel = Parcel.obtain(); 132 ksm.writeToParcel(parcel, 0); 133 134 // Read from it 135 parcel.setDataPosition(0); 136 KeyphraseSoundModel unparceled = KeyphraseSoundModel.CREATOR.createFromParcel(parcel); 137 138 // Verify that they are the same 139 assertEquals(ksm.getUuid(), unparceled.getUuid()); 140 assertEquals(ksm.getType(), unparceled.getType()); 141 assertTrue(Arrays.equals(ksm.getKeyphrases(), unparceled.getKeyphrases())); 142 assertTrue(Arrays.equals(ksm.getData(), unparceled.getData())); 143 } 144 145 @SmallTest testKeyphraseSoundModelParcelUnparcel_noKeyphrases()146 public void testKeyphraseSoundModelParcelUnparcel_noKeyphrases() throws Exception { 147 byte[] data = new byte[10]; 148 mRandom.nextBytes(data); 149 KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), UUID.randomUUID(), 150 data, null); 151 152 // Write to a parcel 153 Parcel parcel = Parcel.obtain(); 154 ksm.writeToParcel(parcel, 0); 155 156 // Read from it 157 parcel.setDataPosition(0); 158 KeyphraseSoundModel unparceled = KeyphraseSoundModel.CREATOR.createFromParcel(parcel); 159 160 // Verify that they are the same 161 assertEquals(ksm, unparceled); 162 } 163 164 @SmallTest testKeyphraseSoundModelParcelUnparcel_zeroKeyphrases()165 public void testKeyphraseSoundModelParcelUnparcel_zeroKeyphrases() throws Exception { 166 byte[] data = new byte[10]; 167 mRandom.nextBytes(data); 168 KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), UUID.randomUUID(), 169 data, new Keyphrase[0]); 170 171 // Write to a parcel 172 Parcel parcel = Parcel.obtain(); 173 ksm.writeToParcel(parcel, 0); 174 175 // Read from it 176 parcel.setDataPosition(0); 177 KeyphraseSoundModel unparceled = KeyphraseSoundModel.CREATOR.createFromParcel(parcel); 178 179 // Verify that they are the same 180 assertEquals(ksm.getUuid(), unparceled.getUuid()); 181 assertEquals(ksm.getType(), unparceled.getType()); 182 assertTrue(Arrays.equals(ksm.getKeyphrases(), unparceled.getKeyphrases())); 183 assertTrue(Arrays.equals(ksm.getData(), unparceled.getData())); 184 } 185 186 @LargeTest testKeyphraseSoundModelParcelUnparcel_largeData()187 public void testKeyphraseSoundModelParcelUnparcel_largeData() throws Exception { 188 Keyphrase[] keyphrases = new Keyphrase[2]; 189 keyphrases[0] = new Keyphrase(1, 0, Locale.forLanguageTag("en-US"), 190 "hello", new int[] {0}); 191 keyphrases[1] = new Keyphrase(2, 0, Locale.forLanguageTag("fr-FR"), 192 "there", new int[] {1, 2}); 193 byte[] data = new byte[200 * 1024]; 194 mRandom.nextBytes(data); 195 KeyphraseSoundModel ksm = new KeyphraseSoundModel(UUID.randomUUID(), UUID.randomUUID(), 196 data, keyphrases); 197 198 // Write to a parcel 199 Parcel parcel = Parcel.obtain(); 200 ksm.writeToParcel(parcel, 0); 201 202 // Read from it 203 parcel.setDataPosition(0); 204 KeyphraseSoundModel unparceled = KeyphraseSoundModel.CREATOR.createFromParcel(parcel); 205 206 // Verify that they are the same 207 assertEquals(ksm.getUuid(), unparceled.getUuid()); 208 assertEquals(ksm.getType(), unparceled.getType()); 209 assertTrue(Arrays.equals(ksm.getData(), unparceled.getData())); 210 assertTrue(Arrays.equals(ksm.getKeyphrases(), unparceled.getKeyphrases())); 211 } 212 213 @SmallTest testRecognitionEventParcelUnparcel_noData()214 public void testRecognitionEventParcelUnparcel_noData() throws Exception { 215 RecognitionEvent re = new RecognitionEvent(SoundTrigger.RECOGNITION_STATUS_SUCCESS, 216 1 /* soundModelHandle */, 217 true /* captureAvailable */, 218 2 /* captureSession */, 219 3 /* captureDelayMs */, 220 4 /* capturePreambleMs */, 221 false /* triggerInData */, 222 new AudioFormat.Builder() 223 .setSampleRate(16000) 224 .setEncoding(AudioFormat.ENCODING_PCM_16BIT) 225 .setChannelMask(AudioFormat.CHANNEL_IN_MONO) 226 .build(), 227 null /* data */, 228 12345678 /* halEventReceivedMillis */); 229 230 // Write to a parcel 231 Parcel parcel = Parcel.obtain(); 232 re.writeToParcel(parcel, 0); 233 234 // Read from it 235 parcel.setDataPosition(0); 236 RecognitionEvent unparceled = RecognitionEvent.CREATOR.createFromParcel(parcel); 237 238 // Verify that they are the same 239 assertEquals(re, unparceled); 240 } 241 242 @SmallTest testRecognitionEventParcelUnparcel_zeroData()243 public void testRecognitionEventParcelUnparcel_zeroData() throws Exception { 244 RecognitionEvent re = new RecognitionEvent(SoundTrigger.RECOGNITION_STATUS_FAILURE, 245 1 /* soundModelHandle */, 246 true /* captureAvailable */, 247 2 /* captureSession */, 248 3 /* captureDelayMs */, 249 4 /* capturePreambleMs */, 250 false /* triggerInData */, 251 new AudioFormat.Builder() 252 .setSampleRate(16000) 253 .setEncoding(AudioFormat.ENCODING_PCM_16BIT) 254 .setChannelMask(AudioFormat.CHANNEL_IN_MONO) 255 .build(), 256 new byte[1] /* data */, 257 12345678 /* halEventReceivedMillis */); 258 259 // Write to a parcel 260 Parcel parcel = Parcel.obtain(); 261 re.writeToParcel(parcel, 0); 262 263 // Read from it 264 parcel.setDataPosition(0); 265 RecognitionEvent unparceled = RecognitionEvent.CREATOR.createFromParcel(parcel); 266 267 // Verify that they are the same 268 assertEquals(re, unparceled); 269 } 270 271 @SmallTest testRecognitionEventParcelUnparcel_largeData()272 public void testRecognitionEventParcelUnparcel_largeData() throws Exception { 273 byte[] data = new byte[200 * 1024]; 274 mRandom.nextBytes(data); 275 RecognitionEvent re = new RecognitionEvent(SoundTrigger.RECOGNITION_STATUS_ABORT, 276 1 /* soundModelHandle */, 277 false /* captureAvailable */, 278 2 /* captureSession */, 279 3 /* captureDelayMs */, 280 4 /* capturePreambleMs */, 281 false /* triggerInData */, 282 new AudioFormat.Builder() 283 .setSampleRate(16000) 284 .setEncoding(AudioFormat.ENCODING_PCM_16BIT) 285 .setChannelMask(AudioFormat.CHANNEL_IN_MONO) 286 .build(), 287 data, 288 12345678 /* halEventReceivedMillis */); 289 290 // Write to a parcel 291 Parcel parcel = Parcel.obtain(); 292 re.writeToParcel(parcel, 0); 293 294 // Read from it 295 parcel.setDataPosition(0); 296 RecognitionEvent unparceled = RecognitionEvent.CREATOR.createFromParcel(parcel); 297 298 // Verify that they are the same 299 assertEquals(re, unparceled); 300 } 301 302 @SmallTest testRecognitionEventParcelUnparcel_largeAudioData()303 public void testRecognitionEventParcelUnparcel_largeAudioData() throws Exception { 304 byte[] data = new byte[200 * 1024]; 305 mRandom.nextBytes(data); 306 RecognitionEvent re = new RecognitionEvent(SoundTrigger.RECOGNITION_STATUS_ABORT, 307 1 /* soundModelHandle */, 308 false /* captureAvailable */, 309 2 /* captureSession */, 310 3 /* captureDelayMs */, 311 4 /* capturePreambleMs */, 312 true /* triggerInData */, 313 new AudioFormat.Builder() 314 .setChannelMask(AudioFormat.CHANNEL_IN_MONO) 315 .setEncoding(AudioFormat.ENCODING_PCM_16BIT) 316 .setSampleRate(16000) 317 .build(), 318 data, 319 12345678 /* halEventReceivedMillis */); 320 321 // Write to a parcel 322 Parcel parcel = Parcel.obtain(); 323 re.writeToParcel(parcel, 0); 324 325 // Read from it 326 parcel.setDataPosition(0); 327 RecognitionEvent unparceled = RecognitionEvent.CREATOR.createFromParcel(parcel); 328 329 // Verify that they are the same 330 assertEquals(re, unparceled); 331 } 332 333 @SmallTest testKeyphraseRecognitionEventParcelUnparcel_noKeyphrases()334 public void testKeyphraseRecognitionEventParcelUnparcel_noKeyphrases() throws Exception { 335 KeyphraseRecognitionEvent re = new KeyphraseRecognitionEvent( 336 SoundTrigger.RECOGNITION_STATUS_SUCCESS, 337 1 /* soundModelHandle */, 338 true /* captureAvailable */, 339 2 /* captureSession */, 340 3 /* captureDelayMs */, 341 4 /* capturePreambleMs */, 342 false /* triggerInData */, 343 new AudioFormat.Builder() 344 .setSampleRate(16000) 345 .setEncoding(AudioFormat.ENCODING_PCM_16BIT) 346 .setChannelMask(AudioFormat.CHANNEL_IN_MONO) 347 .build(), 348 null /* data */, 349 null /* keyphraseExtras */, 350 12345678 /* halEventReceivedMillis */, 351 new Binder() /* token */); 352 353 // Write to a parcel 354 Parcel parcel = Parcel.obtain(); 355 re.writeToParcel(parcel, 0); 356 357 // Read from it 358 parcel.setDataPosition(0); 359 KeyphraseRecognitionEvent unparceled = 360 KeyphraseRecognitionEvent.CREATOR.createFromParcel(parcel); 361 362 // Verify that they are the same 363 assertEquals(re, unparceled); 364 } 365 366 @SmallTest testKeyphraseRecognitionEventParcelUnparcel_zeroData()367 public void testKeyphraseRecognitionEventParcelUnparcel_zeroData() throws Exception { 368 KeyphraseRecognitionExtra[] kpExtra = new KeyphraseRecognitionExtra[0]; 369 KeyphraseRecognitionEvent re = new KeyphraseRecognitionEvent( 370 SoundTrigger.RECOGNITION_STATUS_FAILURE, 371 2 /* soundModelHandle */, 372 true /* captureAvailable */, 373 2 /* captureSession */, 374 3 /* captureDelayMs */, 375 4 /* capturePreambleMs */, 376 false /* triggerInData */, 377 new AudioFormat.Builder() 378 .setSampleRate(16000) 379 .setEncoding(AudioFormat.ENCODING_PCM_16BIT) 380 .setChannelMask(AudioFormat.CHANNEL_IN_MONO) 381 .build(), 382 new byte[1] /* data */, 383 kpExtra, 384 12345678 /* halEventReceivedMillis */, 385 new Binder() /* token */); 386 387 // Write to a parcel 388 Parcel parcel = Parcel.obtain(); 389 re.writeToParcel(parcel, 0); 390 391 // Read from it 392 parcel.setDataPosition(0); 393 KeyphraseRecognitionEvent unparceled = 394 KeyphraseRecognitionEvent.CREATOR.createFromParcel(parcel); 395 396 // Verify that they are the same 397 assertEquals(re, unparceled); 398 } 399 400 @LargeTest testKeyphraseRecognitionEventParcelUnparcel_largeData()401 public void testKeyphraseRecognitionEventParcelUnparcel_largeData() throws Exception { 402 byte[] data = new byte[200 * 1024]; 403 mRandom.nextBytes(data); 404 KeyphraseRecognitionExtra[] kpExtra = new KeyphraseRecognitionExtra[4]; 405 ConfidenceLevel cl1 = new ConfidenceLevel(1, 90); 406 ConfidenceLevel cl2 = new ConfidenceLevel(2, 30); 407 kpExtra[0] = new KeyphraseRecognitionExtra(1, 408 SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION, 0, 409 new ConfidenceLevel[] {cl1, cl2}); 410 kpExtra[1] = new KeyphraseRecognitionExtra(1, 411 SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER, 0, 412 new ConfidenceLevel[] {cl2}); 413 kpExtra[2] = new KeyphraseRecognitionExtra(1, 414 SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER, 0, null); 415 kpExtra[3] = new KeyphraseRecognitionExtra(1, 416 SoundTrigger.RECOGNITION_MODE_VOICE_TRIGGER, 0, 417 new ConfidenceLevel[0]); 418 419 KeyphraseRecognitionEvent re = new KeyphraseRecognitionEvent( 420 SoundTrigger.RECOGNITION_STATUS_FAILURE, 421 1 /* soundModelHandle */, 422 true /* captureAvailable */, 423 2 /* captureSession */, 424 3 /* captureDelayMs */, 425 4 /* capturePreambleMs */, 426 false /* triggerInData */, 427 new AudioFormat.Builder() 428 .setSampleRate(16000) 429 .setEncoding(AudioFormat.ENCODING_PCM_16BIT) 430 .setChannelMask(AudioFormat.CHANNEL_IN_MONO) 431 .build(), 432 data, 433 kpExtra, 434 12345678 /* halEventReceivedMillis */, 435 new Binder() /* token */); 436 437 // Write to a parcel 438 Parcel parcel = Parcel.obtain(); 439 re.writeToParcel(parcel, 0); 440 441 // Read from it 442 parcel.setDataPosition(0); 443 KeyphraseRecognitionEvent unparceled = 444 KeyphraseRecognitionEvent.CREATOR.createFromParcel(parcel); 445 446 // Verify that they are the same 447 assertEquals(re, unparceled); 448 } 449 } 450