1 /*
2  * Copyright (C) 2019 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_middleware;
18 
19 import android.annotation.Nullable;
20 import android.media.soundtrigger.ConfidenceLevel;
21 import android.media.soundtrigger.ModelParameter;
22 import android.media.soundtrigger.Phrase;
23 import android.media.soundtrigger.PhraseRecognitionExtra;
24 import android.media.soundtrigger.PhraseSoundModel;
25 import android.media.soundtrigger.RecognitionConfig;
26 import android.media.soundtrigger.RecognitionMode;
27 import android.media.soundtrigger.SoundModel;
28 import android.media.soundtrigger.SoundModelType;
29 
30 import java.util.Objects;
31 import java.util.regex.Matcher;
32 
33 /**
34  * Utilities for asserting the validity of various data types used by this module.
35  * Each of the methods below would throw an {@link IllegalArgumentException} if its input is
36  * invalid. The input's validity is determined irrespective of any context. In cases where the valid
37  * value space is further limited by state, it is the caller's responsibility to assert.
38  *
39  * @hide
40  */
41 public class ValidationUtil {
validateUuid(@ullable String uuid)42     static void validateUuid(@Nullable String uuid) {
43         Objects.requireNonNull(uuid);
44         Matcher matcher = UuidUtil.PATTERN.matcher(uuid);
45         if (!matcher.matches()) {
46             throw new IllegalArgumentException(
47                     "Illegal format for UUID: " + uuid);
48         }
49     }
50 
validateGenericModel(@ullable SoundModel model)51     static void validateGenericModel(@Nullable SoundModel model) {
52         validateModel(model, SoundModelType.GENERIC);
53     }
54 
validateModel(@ullable SoundModel model, int expectedType)55     static void validateModel(@Nullable SoundModel model, int expectedType) {
56         Objects.requireNonNull(model);
57         if (model.type != expectedType) {
58             throw new IllegalArgumentException("Invalid type");
59         }
60         validateUuid(model.uuid);
61         validateUuid(model.vendorUuid);
62         if (model.dataSize > 0) {
63             Objects.requireNonNull(model.data);
64         }
65     }
66 
validatePhraseModel(@ullable PhraseSoundModel model)67     static void validatePhraseModel(@Nullable PhraseSoundModel model) {
68         Objects.requireNonNull(model);
69         validateModel(model.common, SoundModelType.KEYPHRASE);
70         Objects.requireNonNull(model.phrases);
71         for (Phrase phrase : model.phrases) {
72             Objects.requireNonNull(phrase);
73             if ((phrase.recognitionModes & ~(RecognitionMode.VOICE_TRIGGER
74                     | RecognitionMode.USER_IDENTIFICATION | RecognitionMode.USER_AUTHENTICATION
75                     | RecognitionMode.GENERIC_TRIGGER)) != 0) {
76                 throw new IllegalArgumentException("Invalid recognitionModes");
77             }
78             Objects.requireNonNull(phrase.users);
79             Objects.requireNonNull(phrase.locale);
80             Objects.requireNonNull(phrase.text);
81         }
82     }
83 
validateRecognitionConfig(@ullable RecognitionConfig config)84     static void validateRecognitionConfig(@Nullable RecognitionConfig config) {
85         Objects.requireNonNull(config);
86         Objects.requireNonNull(config.phraseRecognitionExtras);
87         for (PhraseRecognitionExtra extra : config.phraseRecognitionExtras) {
88             Objects.requireNonNull(extra);
89             if ((extra.recognitionModes & ~(RecognitionMode.VOICE_TRIGGER
90                     | RecognitionMode.USER_IDENTIFICATION | RecognitionMode.USER_AUTHENTICATION
91                     | RecognitionMode.GENERIC_TRIGGER)) != 0) {
92                 throw new IllegalArgumentException("Invalid recognitionModes");
93             }
94             if (extra.confidenceLevel < 0 || extra.confidenceLevel > 100) {
95                 throw new IllegalArgumentException("Invalid confidenceLevel");
96             }
97             Objects.requireNonNull(extra.levels);
98             for (ConfidenceLevel level : extra.levels) {
99                 Objects.requireNonNull(level);
100                 if (level.levelPercent < 0 || level.levelPercent > 100) {
101                     throw new IllegalArgumentException("Invalid confidenceLevel");
102                 }
103             }
104         }
105         Objects.requireNonNull(config.data);
106     }
107 
validateModelParameter(int modelParam)108     static void validateModelParameter(int modelParam) {
109         switch (modelParam) {
110             case ModelParameter.THRESHOLD_FACTOR:
111                 return;
112 
113             default:
114                 throw new IllegalArgumentException("Invalid model parameter");
115         }
116     }
117 }
118