Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 15cecddc authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Add getAudioLocation implementation"

parents f8d97dea 29f38f45
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ static jmethodID method_onConnectionStateChanged;
static jmethodID method_onGroupStatus;
static jmethodID method_onGroupNodeStatus;
static jmethodID method_onAudioConf;
static jmethodID method_onSinkAudioLocationAvailable;

static struct {
  jclass clazz;
@@ -129,6 +130,28 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks {
                                 (jint)sink_audio_location,
                                 (jint)source_audio_location, (jint)avail_cont);
  }

  void OnSinkAudioLocationAvailable(const RawAddress& bd_addr,
                                    uint32_t sink_audio_location) override {
    LOG(INFO) << __func__;

    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return;

    ScopedLocalRef<jbyteArray> addr(
        sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
    if (!addr.get()) {
      LOG(ERROR) << "Failed to new jbyteArray bd addr for group status";
      return;
    }

    sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
                                     (jbyte*)&bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj,
                                 method_onSinkAudioLocationAvailable,
                                 addr.get(), (jint)sink_audio_location);
  }
};

static LeAudioClientCallbacksImpl sLeAudioClientCallbacks;
@@ -145,6 +168,8 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
  method_onGroupNodeStatus =
      env->GetMethodID(clazz, "onGroupNodeStatus", "([BII)V");
  method_onAudioConf = env->GetMethodID(clazz, "onAudioConf", "(IIIII)V");
  method_onSinkAudioLocationAvailable =
      env->GetMethodID(clazz, "onSinkAudioLocationAvailable", "([BI)V");
  method_onConnectionStateChanged =
      env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");
}
+12 −0
Original line number Diff line number Diff line
@@ -141,6 +141,18 @@ public class LeAudioNativeInterface {
        sendMessageToService(event);
    }

    private void onSinkAudioLocationAvailable(byte[] address, int sinkAudioLocation) {
        LeAudioStackEvent event =
                new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE);
        event.device = getDevice(address);
        event.valueInt1 = sinkAudioLocation;

        if (DBG) {
            Log.d(TAG, "onSinkAudioLocationAvailable: " + event);
        }
        sendMessageToService(event);
    }

    /**
     * Initializes the native interface.
     *
+43 −0
Original line number Diff line number Diff line
@@ -143,6 +143,7 @@ public class LeAudioService extends ProfileService {
    private final Map<BluetoothDevice, LeAudioStateMachine> mStateMachines = new LinkedHashMap<>();

    private final Map<BluetoothDevice, Integer> mDeviceGroupIdMap = new ConcurrentHashMap<>();
    private final Map<BluetoothDevice, Integer> mDeviceAudioLocationMap = new ConcurrentHashMap<>();

    private final int mContextSupportingInputAudio =
            BluetoothLeAudio.CONTEXT_TYPE_COMMUNICATION |
@@ -203,6 +204,7 @@ public class LeAudioService extends ProfileService {
        mStateMachinesThread.start();

        mDeviceGroupIdMap.clear();
        mDeviceAudioLocationMap.clear();
        mBroadcastStateMap.clear();
        mBroadcastIdMap.clear();
        mBroadcastMetadataList.clear();
@@ -290,6 +292,7 @@ public class LeAudioService extends ProfileService {
        }

        mDeviceGroupIdMap.clear();
        mDeviceAudioLocationMap.clear();
        mGroupDescriptors.clear();

        if (mBroadcastCallbacks != null) {
@@ -1049,6 +1052,17 @@ public class LeAudioService extends ProfileService {
            intent.putExtra(BluetoothLeAudio.EXTRA_LE_AUDIO_SINK_LOCATION, snk_audio_location);
            intent.putExtra(BluetoothLeAudio.EXTRA_LE_AUDIO_SOURCE_LOCATION, src_audio_location);
            intent.putExtra(BluetoothLeAudio.EXTRA_LE_AUDIO_AVAILABLE_CONTEXTS, available_contexts);
        } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE) {
            Objects.requireNonNull(stackEvent.device,
                    "Device should never be null, event: " + stackEvent);

            int sink_audio_location = stackEvent.valueInt1;
            mDeviceAudioLocationMap.put(device, sink_audio_location);

            if (DBG) {
                Log.i(TAG, "EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE:" + device
                        + " audio location:" + sink_audio_location);
            }
        } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED) {
            int group_id = stackEvent.valueInt1;
            int group_status = stackEvent.valueInt2;
@@ -1263,6 +1277,7 @@ public class LeAudioService extends ProfileService {
        }

        mDeviceGroupIdMap.remove(device);
        mDeviceAudioLocationMap.remove(device);
        synchronized (mStateMachines) {
            LeAudioStateMachine sm = mStateMachines.get(device);
            if (sm == null) {
@@ -1423,6 +1438,19 @@ public class LeAudioService extends ProfileService {
        return true;
    }

    /**
     * Get device audio location.
     * @param device LE Audio capable device
     * @return the sink audioi location that this device currently exposed
     */
    public int getAudioLocation(BluetoothDevice device) {
        if (device == null) {
            return BluetoothLeAudio.AUDIO_LOCATION_INVALID;
        }
        return mDeviceAudioLocationMap.getOrDefault(device,
                BluetoothLeAudio.AUDIO_LOCATION_INVALID);
    }

    /**
     * Set connection policy of the profile and connects it if connectionPolicy is
     * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is
@@ -1887,6 +1915,21 @@ public class LeAudioService extends ProfileService {
            }
        }

        @Override
        public void getAudioLocation(BluetoothDevice device, AttributionSource source,
                SynchronousResultReceiver receiver) {
            try {
                LeAudioService service = getService(source);
                int defaultValue = BluetoothLeAudio.AUDIO_LOCATION_INVALID;
                if (service != null) {
                    defaultValue = service.getAudioLocation(device);
                }
                receiver.send(defaultValue);
            } catch (RuntimeException e) {
                receiver.propagateException(e);
            }
        }

        @Override
        public void setConnectionPolicy(BluetoothDevice device, int connectionPolicy,
                AttributionSource source, SynchronousResultReceiver receiver) {
+6 −1
Original line number Diff line number Diff line
@@ -30,8 +30,9 @@ public class LeAudioStackEvent {
    public static final int EVENT_TYPE_GROUP_STATUS_CHANGED = 2;
    public static final int EVENT_TYPE_GROUP_NODE_STATUS_CHANGED = 3;
    public static final int EVENT_TYPE_AUDIO_CONF_CHANGED = 4;
    public static final int EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE = 5;
        // -------- DO NOT PUT ANY NEW UNICAST EVENTS BELOW THIS LINE-------------
    public static final int EVENT_TYPE_UNICAST_MAX = 5;
    public static final int EVENT_TYPE_UNICAST_MAX = 6;

    // Broadcast related events
    public static final int EVENT_TYPE_BROADCAST_CREATED = EVENT_TYPE_UNICAST_MAX + 1;
@@ -103,6 +104,8 @@ public class LeAudioStackEvent {
                return "EVENT_TYPE_GROUP_NODE_STATUS_CHANGED";
            case EVENT_TYPE_AUDIO_CONF_CHANGED:
                return "EVENT_TYPE_AUDIO_CONF_CHANGED";
            case EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE:
                return "EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE";
            case EVENT_TYPE_BROADCAST_CREATED:
                return "EVENT_TYPE_BROADCAST_CREATED";
            case EVENT_TYPE_BROADCAST_DESTROYED:
@@ -138,6 +141,8 @@ public class LeAudioStackEvent {
            case EVENT_TYPE_AUDIO_CONF_CHANGED:
                // FIXME: It should have proper direction names here
                return "{direction:" + value + "}";
            case EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE:
                return "{sink_audio_location:" + value + "}";
            case EVENT_TYPE_BROADCAST_CREATED:
                return "{instance_id:" + value + "}";
            case EVENT_TYPE_BROADCAST_DESTROYED:
+8 −3
Original line number Diff line number Diff line
@@ -1268,9 +1268,14 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
        if (service == null) {
            Log.w(TAG, "Proxy not attached to service");
            if (DBG) log(Log.getStackTraceString(new Throwable()));
        } else if (mAdapter.isEnabled()) {
            //TODO: add the implementation.
            if (VDBG) log("getAudioLocation() from LE audio service");
        } else if (mAdapter.isEnabled() && isValidDevice(device)) {
            try {
                final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
                service.getAudioLocation(device, mAttributionSource, recv);
                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultLocation);
            } catch (RemoteException | TimeoutException e) {
                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
            }
        }
        return defaultLocation;
    }
Loading