Merge "AudioService: Pick head tracking sensor based on UUID"
This commit is contained in:
@@ -59,6 +59,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
|
||||
@@ -1794,4 +1795,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
UUID getDeviceSensorUuid(AudioDeviceAttributes device) {
|
||||
synchronized (mDeviceStateLock) {
|
||||
return mDeviceInventory.getDeviceSensorUuid(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,9 @@ import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Class to manage the inventory of all connected devices.
|
||||
@@ -185,12 +187,20 @@ public class AudioDeviceInventory {
|
||||
final @NonNull String mDeviceName;
|
||||
final @NonNull String mDeviceAddress;
|
||||
int mDeviceCodecFormat;
|
||||
final UUID mSensorUuid;
|
||||
|
||||
DeviceInfo(int deviceType, String deviceName, String deviceAddress, int deviceCodecFormat) {
|
||||
DeviceInfo(int deviceType, String deviceName, String deviceAddress,
|
||||
int deviceCodecFormat, UUID sensorUuid) {
|
||||
mDeviceType = deviceType;
|
||||
mDeviceName = deviceName == null ? "" : deviceName;
|
||||
mDeviceAddress = deviceAddress == null ? "" : deviceAddress;
|
||||
mDeviceCodecFormat = deviceCodecFormat;
|
||||
mSensorUuid = sensorUuid;
|
||||
}
|
||||
|
||||
DeviceInfo(int deviceType, String deviceName, String deviceAddress,
|
||||
int deviceCodecFormat) {
|
||||
this(deviceType, deviceName, deviceAddress, deviceCodecFormat, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -199,7 +209,8 @@ public class AudioDeviceInventory {
|
||||
+ " (" + AudioSystem.getDeviceName(mDeviceType)
|
||||
+ ") name:" + mDeviceName
|
||||
+ " addr:" + mDeviceAddress
|
||||
+ " codec: " + Integer.toHexString(mDeviceCodecFormat) + "]";
|
||||
+ " codec: " + Integer.toHexString(mDeviceCodecFormat)
|
||||
+ " sensorUuid: " + Objects.toString(mSensorUuid) + "]";
|
||||
}
|
||||
|
||||
@NonNull String getKey() {
|
||||
@@ -980,8 +991,13 @@ public class AudioDeviceInventory {
|
||||
// Reset A2DP suspend state each time a new sink is connected
|
||||
mAudioSystem.setParameters("A2dpSuspended=false");
|
||||
|
||||
// The convention for head tracking sensors associated with A2DP devices is to
|
||||
// use a UUID derived from the MAC address as follows:
|
||||
// time_low = 0, time_mid = 0, time_hi = 0, clock_seq = 0, node = MAC Address
|
||||
UUID sensorUuid = UuidUtils.uuidFromAudioDeviceAttributes(
|
||||
new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address));
|
||||
final DeviceInfo di = new DeviceInfo(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, name,
|
||||
address, a2dpCodec);
|
||||
address, a2dpCodec, sensorUuid);
|
||||
final String diKey = di.getKey();
|
||||
mConnectedDevices.put(diKey, di);
|
||||
// on a connection always overwrite the device seen by AudioPolicy, see comment above when
|
||||
@@ -1456,6 +1472,17 @@ public class AudioDeviceInventory {
|
||||
mDevRoleCapturePresetDispatchers.finishBroadcast();
|
||||
}
|
||||
|
||||
UUID getDeviceSensorUuid(AudioDeviceAttributes device) {
|
||||
final String key = DeviceInfo.makeDeviceListKey(device.getInternalType(),
|
||||
device.getAddress());
|
||||
synchronized (mDevicesLock) {
|
||||
DeviceInfo di = mConnectedDevices.get(key);
|
||||
if (di == null) {
|
||||
return null;
|
||||
}
|
||||
return di.mSensorUuid;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------
|
||||
// For tests only
|
||||
|
||||
|
||||
@@ -190,6 +190,7 @@ import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@@ -11017,6 +11018,10 @@ public class AudioService extends IAudioService.Stub
|
||||
return delayMillis;
|
||||
}
|
||||
|
||||
UUID getDeviceSensorUuid(AudioDeviceAttributes device) {
|
||||
return mDeviceBroker.getDeviceSensorUuid(device);
|
||||
}
|
||||
|
||||
//======================
|
||||
// misc
|
||||
//======================
|
||||
|
||||
@@ -43,6 +43,7 @@ import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A helper class to manage Spatializer related functionality
|
||||
@@ -168,6 +169,7 @@ public class SpatializerHelper {
|
||||
return;
|
||||
}
|
||||
mState = STATE_DISABLED_UNAVAILABLE;
|
||||
mASA.getDevicesForAttributes(DEFAULT_ATTRIBUTES).toArray(ROUTING_DEVICES);
|
||||
// note at this point mSpat is still not instantiated
|
||||
}
|
||||
|
||||
@@ -204,6 +206,11 @@ public class SpatializerHelper {
|
||||
logd("onRoutingUpdated: can spatialize media 5.1:" + able
|
||||
+ " on device:" + ROUTING_DEVICES[0]);
|
||||
setDispatchAvailableState(able);
|
||||
|
||||
if (mDesiredHeadTrackingMode != Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED
|
||||
&& mDesiredHeadTrackingMode != Spatializer.HEAD_TRACKING_MODE_DISABLED) {
|
||||
postInitSensors();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
@@ -909,12 +916,21 @@ public class SpatializerHelper {
|
||||
}
|
||||
}
|
||||
// initialize sensor handles
|
||||
// TODO-HT update to non-private sensor once head tracker sensor is defined
|
||||
for (Sensor sensor : mSensorManager.getDynamicSensorList(
|
||||
Sensor.TYPE_DEVICE_PRIVATE_BASE)) {
|
||||
if (sensor.getStringType().equals(HEADTRACKER_SENSOR)) {
|
||||
headHandle = sensor.getHandle();
|
||||
break;
|
||||
UUID routingDeviceUuid = mAudioService.getDeviceSensorUuid(ROUTING_DEVICES[0]);
|
||||
List<Sensor> sensors = new ArrayList<Sensor>(0);
|
||||
sensors.addAll(mSensorManager.getDynamicSensorList(Sensor.TYPE_HEAD_TRACKER));
|
||||
sensors.addAll(mSensorManager.getDynamicSensorList(Sensor.TYPE_DEVICE_PRIVATE_BASE));
|
||||
for (Sensor sensor : sensors) {
|
||||
if (sensor.getType() == Sensor.TYPE_HEAD_TRACKER
|
||||
|| sensor.getStringType().equals(HEADTRACKER_SENSOR)) {
|
||||
UUID uuid = sensor.getUuid();
|
||||
if (uuid.equals(routingDeviceUuid)) {
|
||||
headHandle = sensor.getHandle();
|
||||
break;
|
||||
}
|
||||
if (uuid.equals(UuidUtils.STANDALONE_UUID)) {
|
||||
headHandle = sensor.getHandle();
|
||||
}
|
||||
}
|
||||
}
|
||||
Sensor screenSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
|
||||
|
||||
70
services/core/java/com/android/server/audio/UuidUtils.java
Normal file
70
services/core/java/com/android/server/audio/UuidUtils.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 com.android.server.audio;
|
||||
|
||||
import android.media.AudioDeviceAttributes;
|
||||
import android.media.AudioSystem;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* UuidUtils class implements helper functions to handle unique identifiers
|
||||
* used to associate head tracking sensors to audio devices.
|
||||
*/
|
||||
class UuidUtils {
|
||||
private static final String TAG = "AudioService.UuidUtils";
|
||||
|
||||
private static final long LSB_PREFIX_MASK = 0xFFFF000000000000L;
|
||||
private static final long LSB_SUFFIX_MASK = 0x0000FFFFFFFFFFFFL;
|
||||
// The sensor UUID for Bluetooth devices is defined as follows:
|
||||
// - 8 most significant bytes: All 0s
|
||||
// - 8 most significant bytes: Ascii B, Ascii T, Device MAC address on 6 bytes
|
||||
private static final long LSB_PREFIX_BT = 0x4254000000000000L;
|
||||
|
||||
/**
|
||||
* Special UUID for a head tracking sensor not associated with an audio device.
|
||||
*/
|
||||
public static final UUID STANDALONE_UUID = new UUID(0, 0);
|
||||
|
||||
/**
|
||||
* Generate a headtracking UUID from AudioDeviceAttributes
|
||||
*/
|
||||
public static UUID uuidFromAudioDeviceAttributes(AudioDeviceAttributes device) {
|
||||
switch (device.getInternalType()) {
|
||||
case AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP:
|
||||
String address = device.getAddress().replace(":", "");
|
||||
if (address.length() != 12) {
|
||||
return null;
|
||||
}
|
||||
address = "0x" + address;
|
||||
long lsb = LSB_PREFIX_BT;
|
||||
try {
|
||||
lsb |= Long.decode(address).longValue();
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
if (AudioService.DEBUG_DEVICES) {
|
||||
Slog.i(TAG, "uuidFromAudioDeviceAttributes lsb: " + Long.toHexString(lsb));
|
||||
}
|
||||
return new UUID(0, lsb);
|
||||
default:
|
||||
// Handle other device types here
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user