Remove STHAL 2.4
This version was only created as an intermediate version for development and was never intended for release. STHAL 3 (AIDL) has feature-parity with this one and is intended for release. Bug: 181996624 Test: Manual verification of soundtrigger use-cases. Change-Id: Ic490bbd0501ec593d741cf612f8fd995b7bb9c4e
This commit is contained in:
parent
b5db1dd146
commit
3f1c392d7e
11 changed files with 1 additions and 838 deletions
|
@ -536,7 +536,7 @@
|
|||
</hal>
|
||||
<hal format="hidl" optional="true">
|
||||
<name>android.hardware.soundtrigger</name>
|
||||
<version>2.3-4</version>
|
||||
<version>2.3</version>
|
||||
<interface>
|
||||
<name>ISoundTriggerHw</name>
|
||||
<instance>default</instance>
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
// This file is autogenerated by hidl-gen -Landroidbp.
|
||||
|
||||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
hidl_interface {
|
||||
name: "android.hardware.soundtrigger@2.4",
|
||||
root: "android.hardware",
|
||||
srcs: [
|
||||
"ISoundTriggerHw.hal",
|
||||
"ISoundTriggerHwCallback.hal",
|
||||
"ISoundTriggerHwGlobalCallback.hal",
|
||||
],
|
||||
interfaces: [
|
||||
"android.hardware.audio.common@2.0",
|
||||
"android.hardware.soundtrigger@2.0",
|
||||
"android.hardware.soundtrigger@2.1",
|
||||
"android.hardware.soundtrigger@2.2",
|
||||
"android.hardware.soundtrigger@2.3",
|
||||
"android.hidl.base@1.0",
|
||||
"android.hidl.safe_union@1.0",
|
||||
],
|
||||
gen_java: true,
|
||||
}
|
|
@ -1,190 +0,0 @@
|
|||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.hardware.soundtrigger@2.4;
|
||||
|
||||
import @2.0::SoundModelHandle;
|
||||
import @2.1::ISoundTriggerHw.SoundModel;
|
||||
import @2.1::ISoundTriggerHw.PhraseSoundModel;
|
||||
import @2.3::ISoundTriggerHw;
|
||||
import @2.3::RecognitionConfig;
|
||||
import ISoundTriggerHwCallback;
|
||||
import ISoundTriggerHwGlobalCallback;
|
||||
|
||||
/**
|
||||
* SoundTrigger HAL interface. Used for hardware recognition of hotwords
|
||||
* and other sounds.
|
||||
*
|
||||
* Important notes about the threading model:
|
||||
* ==========================================
|
||||
* Both this interface and the corresponding callback interface use a synchronized calling
|
||||
* convention. This model comes with some advantages, but also with some risks of deadlocks if the
|
||||
* implementation does not handle this correctly. Please consider the following:
|
||||
* - After stopRecognition() returns no more recognition events for that model may be sent. This
|
||||
* implies that any queues holding such events must be flushed before the call returns and that
|
||||
* may imply that callback from the HAL to the client are done while stopRecognition() is blocked.
|
||||
* This is OK, and supported by the framework.
|
||||
* - Similarly, the same relationship applies between unloadModel() and subsequent callbacks to
|
||||
* modelUnloaded().
|
||||
* - Other than these two cases, calls into the HAL *MAY NOT* block on callbacks from the HAL, or
|
||||
* else deadlock conditions may result, which may be handled by rebooting of the HAL process and
|
||||
* cause service outages.
|
||||
*
|
||||
* Similarly, it is expected that a single call to startRecognition() generates at most one event
|
||||
* (the model automatically becomes stopped when the event occurs, until explicitly started again)
|
||||
* and that after a modelUnloaded() event no more events would be sent regarding the model.
|
||||
* Note that a getModelState() call may generate a recognition event, but this event DOES NOT modify
|
||||
* the model state - the model remains started.
|
||||
*
|
||||
* The HAL is expected to correctly handle a stopRecognition() call even after it sent an event
|
||||
* indicating that recognition is stopped and an unloadModel() call even after it sent an event
|
||||
* indicating that it has been unloaded. This is required in order to prevent race conditions
|
||||
* between these calls. This also implies that model handles should generally not be reused until
|
||||
* explicitly unloaded. To avoid the rare possibility of running out of handles, the framework will
|
||||
* call unloadModel() on models that have been preemptively unloaded by the HAL.
|
||||
*
|
||||
* Due to the asynchronous nature of recognition events and preemptive model unloading, the HAL must
|
||||
* correctly handle requests that would have been valid before an event has been delivered, but
|
||||
* became moot as result of the event. Namely:
|
||||
* - stopRecognition() may be called on a model that has already delivered an event and became
|
||||
* inactive as a result. The HAL must return a successful return code in this case.
|
||||
* - Furthermore, if a model is preemptively unloaded after it triggers (typically, this would
|
||||
* happen when it is first aborted and immediately preemptively unloaded), stopRecognition() may
|
||||
* be called on it. The HAL must return a successful return code in this case.
|
||||
* - startRecognition() may be called on a model that has been preemptively unloaded. In this case,
|
||||
* the HAL must return -EBUSY to indicate that the operation is temporarily unsuccessful.
|
||||
* - unloadSoundModel() may be called on a model that has been preemptively unloaded. The HAL must
|
||||
* return a successful return code in this case.
|
||||
*
|
||||
* Important notes about resource constraints and concurrency
|
||||
* =========================================================
|
||||
* Up until this version, the framework would enforce concurrency constraints expressed by the
|
||||
* Properties presented by the soundtrigger instance. These include constraints on the maximum
|
||||
* amount of models that can be loaded at the same time and on running recognition while capturing
|
||||
* from the microphone.
|
||||
* This version changes the approach for how these constraints are modeled, both offering the HAL
|
||||
* implementation more flexibility and simplifying the framework's job in enforcing these
|
||||
* limitations. Note that there is no change for how the framework behaves with earlier versions,
|
||||
* everything described below only applies to this version and onward.
|
||||
* The way this is achieved is as following:
|
||||
* - The framework will no longer enforce constraints on concurrent loading of models, as expressed
|
||||
* in the Properties.maxSoundModels field (this property is merely a hint at this point and may be
|
||||
* deprecated in the future.
|
||||
* - The framework will no longer enforce constraints on concurrency of audio recording and
|
||||
* soundtrigger operation, as expressed in the Properties.concurrentCapture field (this property
|
||||
* is merely a hint at this point and may be deprecated in the future).
|
||||
* - The framework will no longer enforce constraints on concurrent loading of models, as expressed
|
||||
* in the Properties (these properties are merely hints at this point and may be deprecated in the
|
||||
* future.
|
||||
* - The HAL implementation is free to reject starting of any model at any time by having the
|
||||
* respective start*() method return -EBUSY.
|
||||
* - The HAL implementation is free to reject loading of any model at any time by having the
|
||||
* respective load*() method return -EBUSY.
|
||||
* - The HAL implementation is free to preemptively stop a previously started model at its own
|
||||
* discretion (for example, if a higher priority use-case which cannot coexist with detection
|
||||
* has been requested). The HAL must notify the framework of the preemption by sending a
|
||||
* recognition event with an `ABORT` status. The implementation must NOT attempt to restart the
|
||||
* recognition automatically when conditions change.
|
||||
* - The HAL implementation is free to preemptively unload a previously loaded model at its own
|
||||
* discretion (for example, if a higher-priority model is being loaded and the two cannot
|
||||
* coexist). When doing so, it must first abort the detection if active (as per above) and then
|
||||
* notify the framework of the unload using the newly added modelUnloaded callback.
|
||||
* - When conditions change, such that a model that couldn't previously load or start or that had
|
||||
* previously been preemptively stopped or unloaded, the HAL must notify the framework via the
|
||||
* newly added tryAgain() callback. This callback is not a guarantee that any operation would now
|
||||
* succeed, but merely a hint that retrying something that had previously failed, now MAY succeed.
|
||||
* Until this callback arrives, the framework may assume that any operation that had previously
|
||||
* failed or aborted would still fail if retried, so the implementation should not forget to
|
||||
* deliver it. There are no guarantees regarding how the framework may respond to this event and
|
||||
* the order in which it may choose to reload/restart its models. Typically, as result of this
|
||||
* event the framework will make a single attempt per model to bring this model to its desired
|
||||
* state (loaded, started).
|
||||
*/
|
||||
interface ISoundTriggerHw extends @2.3::ISoundTriggerHw {
|
||||
/**
|
||||
* This will get called at most once per every attachment to the service.
|
||||
*
|
||||
* All events not tied to a specific model should go through this callback.
|
||||
*/
|
||||
registerGlobalCallback(ISoundTriggerHwGlobalCallback callback);
|
||||
|
||||
/**
|
||||
* Load a sound model. Once loaded, recognition of this model can be
|
||||
* started and stopped.
|
||||
* The implementation returns a unique handle used by other functions
|
||||
* (unloadSoundModel(), startRecognition*(), etc...
|
||||
*
|
||||
* Must have the exact same semantics as loadSoundModel from ISoundTriggerHw@2.3 except that the
|
||||
* return values have changed and that there is no cookie provided (the implementation may pass
|
||||
* any value to the callback, as it is ignored).
|
||||
*
|
||||
* @param soundModel A SoundModel structure describing the sound model
|
||||
* to load.
|
||||
* @param callback The callback interface on which the soundModelCallback*()
|
||||
* method must be called upon completion and modelUnloaded() upon preempted unload.
|
||||
* @return retval Operation completion status: 0 in case of success,
|
||||
* -EBUSY in case the operation is temporarily unavailable (but possible in general).
|
||||
* @return modelHandle A unique handle assigned by the HAL for use by the
|
||||
* framework when controlling activity for this sound model.
|
||||
*/
|
||||
loadSoundModel_2_4(SoundModel soundModel, ISoundTriggerHwCallback callback)
|
||||
generates (int32_t retval, SoundModelHandle modelHandle);
|
||||
|
||||
/**
|
||||
* Load a key phrase sound model. Once loaded, recognition of this model can
|
||||
* be started and stopped. Only one active recognition per model at a time.
|
||||
* The SoundTrigger service must handle concurrent recognition requests by
|
||||
* different users/applications on the same model.
|
||||
* The implementation returns a unique handle used by other functions
|
||||
* (unloadSoundModel(), startRecognition*(), etc...
|
||||
*
|
||||
* Must have the exact same semantics as loadPhraseSoundModel from ISoundTriggerHw@2.3 except
|
||||
* that the return values have changed and that there is no cookie provided (the implementation
|
||||
* may pass any value to the callback, as it is ignored).
|
||||
*
|
||||
* @param soundModel A PhraseSoundModel structure describing the sound model
|
||||
* to load.
|
||||
* @param callback The callback interface on which the soundModelCallback*()
|
||||
* method must be called upon completion and modelUnloaded() upon preempted unload.
|
||||
* @return retval Operation completion status: 0 in case of success,
|
||||
* -EBUSY in case the operation is temporarily unavailable (but possible in general).
|
||||
* @return modelHandle A unique handle assigned by the HAL for use by the
|
||||
* framework when controlling activity for this sound model.
|
||||
*/
|
||||
loadPhraseSoundModel_2_4(PhraseSoundModel soundModel, ISoundTriggerHwCallback callback)
|
||||
generates (int32_t retval, SoundModelHandle modelHandle);
|
||||
|
||||
/**
|
||||
* Start recognition on a given model. Only one recognition active
|
||||
* at a time per model. Once recognition succeeds or fails, the callback
|
||||
* associated with the model handle is called.
|
||||
*
|
||||
* Must have the exact same semantics as startRecognition from ISoundTriggerHw@2.3 except that
|
||||
* there are different expectations of the return value and that there is no cookie provided
|
||||
* (the implementation may pass any value to the callback, as it is ignored).
|
||||
*
|
||||
* @param modelHandle the handle of the sound model to use for recognition
|
||||
* @param config A RecognitionConfig structure containing attributes of the
|
||||
* recognition to perform
|
||||
* @param callback The callback interface on which the recognitionCallback()
|
||||
* method must be called upon recognition.
|
||||
* @return retval Operation completion status: 0 in case of success,
|
||||
* -EBUSY in case the operation is temporarily unavailable (but possible in general), or in
|
||||
* case model has been preemtively unloaded.
|
||||
*/
|
||||
startRecognition_2_4(SoundModelHandle modelHandle, RecognitionConfig config)
|
||||
generates (int32_t retval);
|
||||
};
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.hardware.soundtrigger@2.4;
|
||||
|
||||
import @2.0::SoundModelHandle;
|
||||
import @2.1::ISoundTriggerHwCallback;
|
||||
|
||||
/**
|
||||
* SoundTrigger HAL per-model Callback interface.
|
||||
*/
|
||||
interface ISoundTriggerHwCallback extends @2.1::ISoundTriggerHwCallback {
|
||||
/**
|
||||
* Callback method called by the HAL when a model has been unloaded at the HAL implementation's
|
||||
* discretion. Only a stopped model may be unloaded.
|
||||
* This event is NOT sent as part of an unload sequence initiated by the client.
|
||||
*
|
||||
* @param model The model handle.
|
||||
*/
|
||||
modelUnloaded(SoundModelHandle model);
|
||||
};
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.hardware.soundtrigger@2.4;
|
||||
|
||||
/**
|
||||
* SoundTrigger HAL callback interface for events not associated with a particular model.
|
||||
*/
|
||||
interface ISoundTriggerHwGlobalCallback {
|
||||
/**
|
||||
* Callback method called by the HAL whenever internal conditions have been made available, such
|
||||
* that a call that would previously have failed with an -EBUSY status may now succeed.
|
||||
* There is no guarantee that any call would succeed following this event. It is merely a hint
|
||||
* to the client that it may retry.
|
||||
* Conversely, any call that have failed previously with -EBUSY is guaranteed to fail again if
|
||||
* retried, until this callback is delivered.
|
||||
*/
|
||||
onResourcesAvailable();
|
||||
};
|
|
@ -1,17 +0,0 @@
|
|||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
java_binary {
|
||||
name: "sthal_cli_2.4",
|
||||
wrapper: "sthal_cli_2.4",
|
||||
srcs: ["java/**/*.java"],
|
||||
static_libs: [
|
||||
"android.hardware.soundtrigger-V2.4-java",
|
||||
],
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
include /media/java/android/media/soundtrigger_middleware/OWNERS
|
|
@ -1,401 +0,0 @@
|
|||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.hardware.soundtrigger.V2_4.cli;
|
||||
|
||||
import android.hardware.soundtrigger.V2_0.PhraseRecognitionExtra;
|
||||
import android.hardware.soundtrigger.V2_0.RecognitionMode;
|
||||
import android.hardware.soundtrigger.V2_0.SoundModelType;
|
||||
import android.hardware.soundtrigger.V2_3.OptionalModelParameterRange;
|
||||
import android.hardware.soundtrigger.V2_4.ISoundTriggerHw;
|
||||
import android.hardware.soundtrigger.V2_4.ISoundTriggerHwCallback;
|
||||
import android.hardware.soundtrigger.V2_4.ISoundTriggerHwGlobalCallback;
|
||||
import android.os.HidlMemoryUtil;
|
||||
import android.os.HwBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemProperties;
|
||||
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* This is a quick-and-dirty sound trigger HAL console mock.
|
||||
*
|
||||
* It would only work on userdebug builds.
|
||||
*
|
||||
* When this app is started, it will initially:
|
||||
* - Register a ISoundTriggerHw HAL with an instance name "mock".
|
||||
* - Set a sysprop that tells SoundTriggerMiddlewareService to try to connect to the mock instance
|
||||
* rather than the default one.
|
||||
* - Reboot the real (default) HAL.
|
||||
*
|
||||
* In response to that, SoundTriggerMiddlewareService is going to connect to the mock HAL and resume
|
||||
* normal operation.
|
||||
*
|
||||
* Our mock HAL will print to stdout every call it receives as well as expose a basic set of
|
||||
* operations for sending event callbacks to the client. This allows us to simulate the frameworks
|
||||
* behavior in response to different HAL behaviors.
|
||||
*/
|
||||
public class SthalCli {
|
||||
private static SoundTriggerImpl mService;
|
||||
private static final Scanner scanner = new Scanner(System.in);
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
System.out.println("Registering mock STHAL");
|
||||
HwBinder.setTrebleTestingOverride(true);
|
||||
mService = new SoundTriggerImpl();
|
||||
mService.registerAsService("mock");
|
||||
|
||||
System.out.println("Rebooting STHAL");
|
||||
SystemProperties.set("debug.soundtrigger_middleware.use_mock_hal", "2");
|
||||
SystemProperties.set("sys.audio.restart.hal", "1");
|
||||
|
||||
while (processCommand()) ;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
private static void cleanup() {
|
||||
System.out.println("Cleaning up.");
|
||||
SystemProperties.set("debug.soundtrigger_middleware.use_mock_hal", null);
|
||||
HwBinder.setTrebleTestingOverride(false);
|
||||
}
|
||||
|
||||
private static boolean processCommand() {
|
||||
String line = scanner.nextLine();
|
||||
String[] tokens = line.split("\\s+");
|
||||
if (tokens.length < 1) {
|
||||
return false;
|
||||
}
|
||||
switch (tokens[0]) {
|
||||
case "q":
|
||||
return false;
|
||||
|
||||
case "a":
|
||||
mService.sendOnResourcesAvailable();
|
||||
return true;
|
||||
|
||||
case "u":
|
||||
mService.sendModelUnloaded(Integer.parseInt(tokens[1]));
|
||||
return true;
|
||||
|
||||
case "r":
|
||||
mService.sendRecognitionEvent(Integer.parseInt(tokens[1]),
|
||||
Integer.parseInt(tokens[2]));
|
||||
return true;
|
||||
|
||||
case "p":
|
||||
mService.sendPhraseRecognitionEvent(Integer.parseInt(tokens[1]),
|
||||
Integer.parseInt(tokens[2]));
|
||||
return true;
|
||||
|
||||
case "d":
|
||||
mService.dumpModels();
|
||||
return true;
|
||||
|
||||
case "h":
|
||||
System.out.print("Available commands:\n" + "h - help\n" + "q - quit\n"
|
||||
+ "a - send onResourcesAvailable event\n"
|
||||
+ "u <model> - send modelUnloaded event\n"
|
||||
+ "r <model> <status> - send recognitionEvent\n"
|
||||
+ "p <model> <status> - send phraseRecognitionEvent\n"
|
||||
+ "d - dump models\n");
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class SoundTriggerImpl extends ISoundTriggerHw.Stub {
|
||||
static class Model {
|
||||
final ISoundTriggerHwCallback callback;
|
||||
final SoundModel model;
|
||||
final PhraseSoundModel phraseModel;
|
||||
public android.hardware.soundtrigger.V2_3.RecognitionConfig config = null;
|
||||
|
||||
Model(ISoundTriggerHwCallback callback, SoundModel model) {
|
||||
this.callback = callback;
|
||||
this.model = model;
|
||||
this.phraseModel = null;
|
||||
}
|
||||
|
||||
Model(ISoundTriggerHwCallback callback, PhraseSoundModel model) {
|
||||
this.callback = callback;
|
||||
this.model = null;
|
||||
this.phraseModel = model;
|
||||
}
|
||||
}
|
||||
|
||||
private ISoundTriggerHwGlobalCallback mGlobalCallback;
|
||||
private final ConcurrentMap<Integer, Model> mLoadedModels = new ConcurrentHashMap<>();
|
||||
private int mHandleCounter = 1;
|
||||
|
||||
public void dumpModels() {
|
||||
mLoadedModels.forEach((handle, model) -> {
|
||||
System.out.println("+++ Model " + handle);
|
||||
System.out.println(" config = " + model.config);
|
||||
android.hardware.soundtrigger.V2_3.RecognitionConfig recognitionConfig =
|
||||
model.config;
|
||||
if (recognitionConfig != null) {
|
||||
System.out.println(" ACTIVE recognitionConfig = " + recognitionConfig);
|
||||
} else {
|
||||
System.out.println(" INACTIVE");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void sendOnResourcesAvailable() {
|
||||
if (mGlobalCallback != null) {
|
||||
try {
|
||||
mGlobalCallback.onResourcesAvailable();
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendRecognitionEvent(int modelHandle, int status) {
|
||||
Model model = mLoadedModels.get(modelHandle);
|
||||
if (model != null && model.config != null) {
|
||||
android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent event =
|
||||
new android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent();
|
||||
event.header.model = modelHandle;
|
||||
event.header.type = SoundModelType.GENERIC;
|
||||
event.header.status = status;
|
||||
event.header.captureSession = model.config.base.header.captureHandle;
|
||||
event.header.captureAvailable = true;
|
||||
event.header.audioConfig.channelMask = 16;
|
||||
event.header.audioConfig.format = 1;
|
||||
event.header.audioConfig.sampleRateHz = 16000;
|
||||
event.data = HidlMemoryUtil.byteArrayToHidlMemory(new byte[0]);
|
||||
try {
|
||||
model.callback.recognitionCallback_2_1(event, 0);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
model.config = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void sendPhraseRecognitionEvent(int modelHandle, int status) {
|
||||
Model model = mLoadedModels.get(modelHandle);
|
||||
if (model != null && model.config != null) {
|
||||
android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent
|
||||
event =
|
||||
new android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent();
|
||||
event.common.header.model = modelHandle;
|
||||
event.common.header.type = SoundModelType.KEYPHRASE;
|
||||
event.common.header.status = status;
|
||||
event.common.header.captureSession = model.config.base.header.captureHandle;
|
||||
event.common.header.captureAvailable = true;
|
||||
event.common.header.audioConfig.channelMask = 16;
|
||||
event.common.header.audioConfig.format = 1;
|
||||
event.common.header.audioConfig.sampleRateHz = 16000;
|
||||
event.common.data = HidlMemoryUtil.byteArrayToHidlMemory(new byte[0]);
|
||||
if (!model.phraseModel.phrases.isEmpty()) {
|
||||
PhraseRecognitionExtra extra = new PhraseRecognitionExtra();
|
||||
extra.id = model.phraseModel.phrases.get(0).id;
|
||||
extra.confidenceLevel = 100;
|
||||
extra.recognitionModes = model.phraseModel.phrases.get(0).recognitionModes;
|
||||
event.phraseExtras.add(extra);
|
||||
}
|
||||
try {
|
||||
model.callback.phraseRecognitionCallback_2_1(event, 0);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
model.config = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void sendModelUnloaded(int modelHandle) {
|
||||
Model model = mLoadedModels.remove(modelHandle);
|
||||
if (model != null) {
|
||||
try {
|
||||
model.callback.modelUnloaded(modelHandle);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerGlobalCallback(ISoundTriggerHwGlobalCallback callback) {
|
||||
System.out.println("registerGlobalCallback()");
|
||||
mGlobalCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSoundModel_2_4(SoundModel soundModel, ISoundTriggerHwCallback callback,
|
||||
loadSoundModel_2_4Callback _hidl_cb) {
|
||||
int handle = mHandleCounter++;
|
||||
System.out.printf("loadSoundModel_2_4(soundModel=%s) -> %d%n", soundModel, handle);
|
||||
mLoadedModels.put(handle, new Model(callback, soundModel));
|
||||
_hidl_cb.onValues(0, handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadPhraseSoundModel_2_4(PhraseSoundModel soundModel,
|
||||
ISoundTriggerHwCallback callback, loadPhraseSoundModel_2_4Callback _hidl_cb) {
|
||||
int handle = mHandleCounter++;
|
||||
System.out.printf("loadPhraseSoundModel_2_4(soundModel=%s) -> %d%n", soundModel,
|
||||
handle);
|
||||
mLoadedModels.put(handle, new Model(callback, soundModel));
|
||||
_hidl_cb.onValues(0, handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startRecognition_2_4(int modelHandle,
|
||||
android.hardware.soundtrigger.V2_3.RecognitionConfig config) {
|
||||
System.out.printf("startRecognition_2_4(modelHandle=%d)%n", modelHandle);
|
||||
Model model = mLoadedModels.get(modelHandle);
|
||||
if (model != null) {
|
||||
model.config = config;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getProperties_2_3(getProperties_2_3Callback _hidl_cb) {
|
||||
System.out.println("getProperties_2_3()");
|
||||
android.hardware.soundtrigger.V2_3.Properties properties =
|
||||
new android.hardware.soundtrigger.V2_3.Properties();
|
||||
properties.base.implementor = "Android";
|
||||
properties.base.description = "Mock STHAL";
|
||||
properties.base.maxSoundModels = 2;
|
||||
properties.base.maxKeyPhrases = 1;
|
||||
properties.base.recognitionModes =
|
||||
RecognitionMode.VOICE_TRIGGER | RecognitionMode.GENERIC_TRIGGER;
|
||||
_hidl_cb.onValues(0, properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryParameter(int modelHandle, int modelParam,
|
||||
queryParameterCallback _hidl_cb) {
|
||||
_hidl_cb.onValues(0, new OptionalModelParameterRange());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getModelState(int modelHandle) {
|
||||
System.out.printf("getModelState(modelHandle=%d)%n", modelHandle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int unloadSoundModel(int modelHandle) {
|
||||
System.out.printf("unloadSoundModel(modelHandle=%d)%n", modelHandle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopRecognition(int modelHandle) {
|
||||
System.out.printf("stopRecognition(modelHandle=%d)%n", modelHandle);
|
||||
Model model = mLoadedModels.get(modelHandle);
|
||||
if (model != null) {
|
||||
model.config = null;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(android.os.NativeHandle fd, java.util.ArrayList<String> options) {
|
||||
if (!options.isEmpty()) {
|
||||
switch (options.get(0)) {
|
||||
case "reboot":
|
||||
System.out.println("Received a reboot request. Exiting.");
|
||||
cleanup();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Everything below is not implemented and not expected to be called.
|
||||
|
||||
@Override
|
||||
public int startRecognition_2_3(int modelHandle,
|
||||
android.hardware.soundtrigger.V2_3.RecognitionConfig config) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setParameter(int modelHandle, int modelParam, int value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getParameter(int modelHandle, int modelParam, getParameterCallback _hidl_cb) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSoundModel_2_1(SoundModel soundModel,
|
||||
android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback callback, int cookie,
|
||||
loadSoundModel_2_1Callback _hidl_cb) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadPhraseSoundModel_2_1(PhraseSoundModel soundModel,
|
||||
android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback callback, int cookie,
|
||||
loadPhraseSoundModel_2_1Callback _hidl_cb) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startRecognition_2_1(int modelHandle, RecognitionConfig config,
|
||||
android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback callback, int cookie) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getProperties(getPropertiesCallback _hidl_cb) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSoundModel(
|
||||
android.hardware.soundtrigger.V2_0.ISoundTriggerHw.SoundModel soundModel,
|
||||
android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback callback, int cookie,
|
||||
loadSoundModelCallback _hidl_cb) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadPhraseSoundModel(
|
||||
android.hardware.soundtrigger.V2_0.ISoundTriggerHw.PhraseSoundModel soundModel,
|
||||
android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback callback, int cookie,
|
||||
loadPhraseSoundModelCallback _hidl_cb) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startRecognition(int modelHandle,
|
||||
android.hardware.soundtrigger.V2_0.ISoundTriggerHw.RecognitionConfig config,
|
||||
android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback callback, int cookie) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopAllRecognitions() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
#!/system/bin/sh
|
||||
# Script to start "sthal_cli_2.4" on the device
|
||||
#
|
||||
base=/system
|
||||
export CLASSPATH=$base/framework/sthal_cli_2.4.jar
|
||||
exec app_process $base/bin android.hardware.soundtrigger.V2_4.cli.SthalCli "$@"
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2021 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "VtsHalSoundtriggerV2_4TargetTest",
|
||||
defaults: ["VtsHalTargetTestDefaults"],
|
||||
srcs: ["VtsHalSoundtriggerV2_4TargetTest.cpp"],
|
||||
static_libs: [
|
||||
"android.hardware.soundtrigger@2.0",
|
||||
"android.hardware.soundtrigger@2.1",
|
||||
"android.hardware.soundtrigger@2.2",
|
||||
"android.hardware.soundtrigger@2.3",
|
||||
"android.hardware.soundtrigger@2.4",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
"vts",
|
||||
],
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "SoundTriggerHidlHalTest"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android/hardware/audio/common/2.0/types.h>
|
||||
#include <android/hardware/soundtrigger/2.4/ISoundTriggerHwGlobalCallback.h>
|
||||
#include <android/hardware/soundtrigger/2.4/ISoundTriggerHw.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <hidl/GtestPrinter.h>
|
||||
#include <hidl/ServiceManagement.h>
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Status;
|
||||
using ::android::hardware::soundtrigger::V2_4::ISoundTriggerHw;
|
||||
using ::android::hardware::soundtrigger::V2_4::ISoundTriggerHwGlobalCallback;
|
||||
|
||||
/**
|
||||
* Test class holding the instance of the SoundTriggerHW service to test.
|
||||
* The passed parameter is the registered name of the implementing service
|
||||
* supplied by INSTANTIATE_TEST_SUITE_P() call.
|
||||
*/
|
||||
class SoundTriggerHidlTest : public testing::TestWithParam<std::string> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
mSoundtrigger = ISoundTriggerHw::getService(GetParam());
|
||||
|
||||
ASSERT_NE(mSoundtrigger, nullptr);
|
||||
LOG(INFO) << "Test is remote " << mSoundtrigger->isRemote();
|
||||
}
|
||||
|
||||
protected:
|
||||
sp<ISoundTriggerHw> mSoundtrigger;
|
||||
};
|
||||
|
||||
/**
|
||||
* Empty test is in place to ensure service is initialized.
|
||||
* Due to the nature of SoundTrigger HAL providing an interface for
|
||||
* proprietary or vendor specific implementations, limited testing on
|
||||
* individual APIs is possible.
|
||||
*/
|
||||
TEST_P(SoundTriggerHidlTest, ServiceIsInstantiated) {}
|
||||
|
||||
class GlobalCallback : public ISoundTriggerHwGlobalCallback {
|
||||
Return<void> onResourcesAvailable() override {
|
||||
return Status::ok();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Test ISoundTriggerHw::registerGlobalCallback method
|
||||
*
|
||||
* Verifies that:
|
||||
* - the implementation implements the method
|
||||
* - the method returns no error
|
||||
*/
|
||||
TEST_P(SoundTriggerHidlTest, RegisterGlobalCallback) {
|
||||
Return<void> hidlReturn;
|
||||
sp<ISoundTriggerHwGlobalCallback> callback = new GlobalCallback();
|
||||
hidlReturn = mSoundtrigger->registerGlobalCallback(callback);
|
||||
EXPECT_TRUE(hidlReturn.isOk());
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SoundTriggerHidlTest);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
PerInstance, SoundTriggerHidlTest,
|
||||
testing::ValuesIn(android::hardware::getAllHalInstanceNames(ISoundTriggerHw::descriptor)),
|
||||
android::hardware::PrintInstanceNameToString);
|
Loading…
Reference in a new issue