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

Commit 03544e4c authored by William Escande's avatar William Escande
Browse files

AICS: Simplify VolumeControlInputDescriptor usage

Since we are storing the instance with index [0-NumOfInput], we don't
need to store it in a map.
Using an array
re-write unit test to test smaller behavior
re-write accessor method to unify logging
make use of new defined constant for data check

Bug: 372328699
Flag: com.android.bluetooth.flags.aics_api
Test: m Bluetooth
Change-Id: Id5ddfa65c72ae409be5968b2a60ef629da4ca288
parent 504ee538
Loading
Loading
Loading
Loading
+65 −134
Original line number Diff line number Diff line
@@ -16,56 +16,47 @@

package com.android.bluetooth.vc;

import android.bluetooth.BluetoothVolumeControl;
import android.util.Log;

import com.android.bluetooth.btservice.ProfileService;

import java.util.HashMap;
import java.util.Map;

class VolumeControlInputDescriptor {
    private static final String TAG = "VolumeControlInputDescriptor";
    final Map<Integer, Descriptor> mVolumeInputs = new HashMap<>();

    public static final int AUDIO_INPUT_TYPE_UNSPECIFIED = 0x00;
    public static final int AUDIO_INPUT_TYPE_BLUETOOTH = 0x01;
    public static final int AUDIO_INPUT_TYPE_MICROPHONE = 0x02;
    public static final int AUDIO_INPUT_TYPE_ANALOG = 0x03;
    public static final int AUDIO_INPUT_TYPE_DIGITAL = 0x04;
    public static final int AUDIO_INPUT_TYPE_RADIO = 0x05;
    public static final int AUDIO_INPUT_TYPE_STREAMING = 0x06;
    public static final int AUDIO_INPUT_TYPE_AMBIENT = 0x07;
    private static final String TAG = VolumeControlInputDescriptor.class.getSimpleName();

    final Descriptor[] mVolumeInputs;

    VolumeControlInputDescriptor(int numberOfExternalInputs) {
        mVolumeInputs = new Descriptor[numberOfExternalInputs];
        // Stack delivers us number of audio inputs. ids are countinous from [0;n[
        for (int i = 0; i < numberOfExternalInputs; i++) {
            mVolumeInputs[i] = new Descriptor();
        }
    }

    private static class Descriptor {
        /* True when input is active, false otherwise */
        boolean mIsActive = false;
        int mStatus = 0; // AudioInputStatus.INACTIVE;

        /* Defined as in Assigned Numbers in the BluetoothVolumeControl.AUDIO_INPUT_TYPE_ */
        int mType = AUDIO_INPUT_TYPE_UNSPECIFIED;
        int mType = 0; // AudioInputType.UNSPECIFIED;

        int mGainValue = 0;

        /* As per AICS 1.0
         * 3.1.3. Gain_Mode field
         * The Gain_Mode field shall be set to a value that reflects whether gain modes are
         *  manual or automatic.
        /* See AICS 1.0 - 3.1.3. Gain_Mode field
         * The Gain_Mode field shall be set to a value that reflects whether gain modes are manual
         * or automatic.
         * - Manual Only, the server allows only manual gain.
         * - Automatic Only, the server allows only automatic gain.
         *
         * If the Gain_Mode field value is Manual Only, the server allows only manual gain.
         * If the Gain_Mode field is Automatic Only, the server allows only automatic gain.
         *
         * For all other Gain_Mode field values, the server allows switchable
         * automatic/manual gain.
         * For all other Gain_Mode field values, the server allows switchable automatic/manual gain.
         */
        int mGainMode = 0;

        boolean mIsMute = false;

        /* As per AICS 1.0
         * The Gain_Setting (mGainValue) field is a signed value for which a single increment
         * or decrement should result in a corresponding increase or decrease of the input
         * amplitude by the value of the Gain_Setting_Units (mGainSettingsUnits)
         * field of the Gain Setting Properties characteristic value.
        /* See AICS 1.0
         * The Gain_Setting (mGainValue) field is a signed value for which a single increment or
         * decrement should result in a corresponding increase or decrease of the input amplitude by
         * the value of the Gain_Setting_Units (mGainSettingsUnits) field of the Gain Setting
         * Properties characteristic value.
         */
        int mGainSettingsUnits = 0;

@@ -76,147 +67,87 @@ class VolumeControlInputDescriptor {
    }

    int size() {
        return mVolumeInputs.size();
        return mVolumeInputs.length;
    }

    void add(int id) {
        if (!mVolumeInputs.containsKey(id)) {
            mVolumeInputs.put(id, new Descriptor());
        }
    }

    boolean setActive(int id, boolean active) {
        Descriptor desc = mVolumeInputs.get(id);
        if (desc == null) {
            Log.e(TAG, "setActive, Id " + id + " is unknown");
    private boolean isValidId(int id) {
        if (id >= size() || id < 0) {
            Log.e(TAG, "Request fail. Illegal id argument: " + id);
            return false;
        }
        desc.mIsActive = active;
        return true;
    }

    boolean isActive(int id) {
        Descriptor desc = mVolumeInputs.get(id);
        if (desc == null) {
            Log.e(TAG, "isActive, Id " + id + " is unknown");
            return false;
        }
        return desc.mIsActive;
    }

    boolean setDescription(int id, String description) {
        Descriptor desc = mVolumeInputs.get(id);
        if (desc == null) {
            Log.e(TAG, "setDescription, Id " + id + " is unknown");
            return false;
        }
        desc.mDescription = description;
        return true;
    void setStatus(int id, int status) {
        if (!isValidId(id)) return;
        mVolumeInputs[id].mStatus = status;
    }

    String getDescription(int id) {
        Descriptor desc = mVolumeInputs.get(id);
        if (desc == null) {
            Log.e(TAG, "getDescription, Id " + id + " is unknown");
            return null;
        }
        return desc.mDescription;
    int getStatus(int id) {
        if (!isValidId(id)) return 0; // AudioInputStatus.INACTIVE;
        return mVolumeInputs[id].mStatus;
    }

    boolean setType(int id, int type) {
        Descriptor desc = mVolumeInputs.get(id);
        if (desc == null) {
            Log.e(TAG, "setType, Id " + id + " is unknown");
            return false;
    void setDescription(int id, String description) {
        if (!isValidId(id)) return;
        mVolumeInputs[id].mDescription = description;
    }

        if (type > AUDIO_INPUT_TYPE_AMBIENT) {
            Log.e(TAG, "setType, Type " + type + "for id " + id + " is invalid");
            return false;
    String getDescription(int id) {
        if (!isValidId(id)) return null;
        return mVolumeInputs[id].mDescription;
    }

        desc.mType = type;
        return true;
    void setType(int id, int type) {
        if (!isValidId(id)) return;
        mVolumeInputs[id].mType = type;
    }

    int getType(int id) {
        Descriptor desc = mVolumeInputs.get(id);
        if (desc == null) {
            Log.e(TAG, "getType, Id " + id + " is unknown");
            return AUDIO_INPUT_TYPE_UNSPECIFIED;
        }
        return desc.mType;
        if (!isValidId(id)) return 0; // AudioInputType.UNSPECIFIED;
        return mVolumeInputs[id].mType;
    }

    int getGain(int id) {
        Descriptor desc = mVolumeInputs.get(id);
        if (desc == null) {
            Log.e(TAG, "getGain, Id " + id + " is unknown");
            return 0;
        }
        return desc.mGainValue;
        if (!isValidId(id)) return 0;
        return mVolumeInputs[id].mGainValue;
    }

    boolean isMuted(int id) {
        Descriptor desc = mVolumeInputs.get(id);
        if (desc == null) {
            Log.e(TAG, "isMuted, Id " + id + " is unknown");
            return false;
        }
        return desc.mIsMute;
        if (!isValidId(id)) return false;
        return mVolumeInputs[id].mIsMute;
    }

    boolean setPropSettings(int id, int gainUnit, int gainMin, int gainMax) {
        Descriptor desc = mVolumeInputs.get(id);
        if (desc == null) {
            Log.e(TAG, "setPropSettings, Id " + id + " is unknown");
            return false;
        }
    void setPropSettings(int id, int gainUnit, int gainMin, int gainMax) {
        if (!isValidId(id)) return;

        desc.mGainSettingsUnits = gainUnit;
        desc.mGainSettingsMinSetting = gainMin;
        desc.mGainSettingsMaxSetting = gainMax;

        return true;
        mVolumeInputs[id].mGainSettingsUnits = gainUnit;
        mVolumeInputs[id].mGainSettingsMinSetting = gainMin;
        mVolumeInputs[id].mGainSettingsMaxSetting = gainMax;
    }

    boolean setState(int id, int gainValue, int gainMode, boolean mute) {
        Descriptor desc = mVolumeInputs.get(id);
        if (desc == null) {
            Log.e(TAG, "Id " + id + " is unknown");
            return false;
        }
    void setState(int id, int gainValue, int gainMode, boolean mute) {
        if (!isValidId(id)) return;

        Descriptor desc = mVolumeInputs[id];

        if (gainValue > desc.mGainSettingsMaxSetting || gainValue < desc.mGainSettingsMinSetting) {
            Log.e(TAG, "Invalid gainValue " + gainValue);
            return false;
            Log.e(TAG, "Request fail. Illegal gainValue argument: " + gainValue);
            return;
        }

        desc.mGainValue = gainValue;
        desc.mGainMode = gainMode;
        desc.mIsMute = mute;

        return true;
    }

    void remove(int id) {
        Log.d(TAG, "remove, id: " + id);
        mVolumeInputs.remove(id);
    }

    void clear() {
        Log.d(TAG, "clear all inputs");
        mVolumeInputs.clear();
    }

    void dump(StringBuilder sb) {
        for (Map.Entry<Integer, Descriptor> entry : mVolumeInputs.entrySet()) {
            Descriptor desc = entry.getValue();
            Integer id = entry.getKey();
            ProfileService.println(sb, "        id: " + id);
        for (int i = 0; i < mVolumeInputs.length; i++) {
            Descriptor desc = mVolumeInputs[i];
            ProfileService.println(sb, "      id: " + i);
            ProfileService.println(sb, "        description: " + desc.mDescription);
            ProfileService.println(sb, "        type: " + desc.mType);
            ProfileService.println(sb, "        isActive: " + desc.mIsActive);
            ProfileService.println(sb, "        status: " + desc.mStatus);
            ProfileService.println(sb, "        gainValue: " + desc.mGainValue);
            ProfileService.println(sb, "        gainMode: " + desc.mGainMode);
            ProfileService.println(sb, "        mute: " + desc.mIsMute);
+58 −90
Original line number Diff line number Diff line
@@ -935,22 +935,11 @@ public class VolumeControlService extends ProfileService {
    void handleExternalInputs(BluetoothDevice device, int numberOfExternalInputs) {
        if (numberOfExternalInputs == 0) {
            Log.i(TAG, "Volume offset not available");
            mAudioInputs.remove(device);
            return;
        }

        VolumeControlInputDescriptor inputs = mAudioInputs.get(device);
        if (inputs == null) {
            inputs = new VolumeControlInputDescriptor();
            mAudioInputs.put(device, inputs);
        } else if (inputs.size() != numberOfExternalInputs) {
            Log.i(TAG, "Number of inputs changed: ");
            inputs.clear();
        }

        // Stack delivers us number of audio inputs. ids are countinous from [0;n[
        for (int i = 0; i < numberOfExternalInputs; i++) {
            inputs.add(i);
        }
        mAudioInputs.put(device, new VolumeControlInputDescriptor(numberOfExternalInputs));
    }

    void handleDeviceAvailable(
@@ -1034,133 +1023,112 @@ public class VolumeControlService extends ProfileService {

    void handleDeviceExtInputStateChanged(
            BluetoothDevice device, int id, int gainValue, int gainMode, boolean mute) {
        Log.d(
                TAG,
                ("handleDeviceExtInputStateChanged, device: " + device)
                        + (" inputId: " + id)
        String logInfo =
                "handleDeviceExtInputStateChanged("
                        + ("device:" + device)
                        + (", id" + id)
                        + (" gainValue: " + gainValue)
                        + (" gainMode: " + gainMode)
                        + (" mute: " + mute));
                        + (" mute: " + mute)
                        + ")";

        VolumeControlInputDescriptor input = mAudioInputs.get(device);
        if (input == null) {
            Log.e(
                    TAG,
                    ("handleDeviceExtInputStateChanged, inputId: " + id)
                            + (" not found for device: " + device));
            Log.e(TAG, logInfo + " This device has no audio input control");
            return;
        }
        if (!input.setState(id, gainValue, gainMode, mute)) {
            Log.e(
                    TAG,
                    ("handleDeviceExtInputStateChanged, error while setting inputId: " + id)
                            + ("for: " + device));
        }

        Log.d(TAG, logInfo);
        input.setState(id, gainValue, gainMode, mute);
    }

    void handleDeviceExtInputStatusChanged(BluetoothDevice device, int id, int status) {
        Log.d(TAG, " device: " + device + " inputId: " + id + " status: " + status);
        String logInfo =
                "handleDeviceExtInputStatusChanged("
                        + ("device:" + device)
                        + (", id" + id)
                        + (", status" + status)
                        + ")";

        VolumeControlInputDescriptor input = mAudioInputs.get(device);
        if (input == null) {
            Log.e(TAG, " inputId: " + id + " not found for device: " + device);
            Log.e(TAG, logInfo + " This device has no audio input control");
            return;
        }

        /*
         * As per ACIS 1.0. Status
         * Inactive: 0x00
         * Active: 0x01
         */
        if (status > 1 || status < 0) {
            Log.e(
                    TAG,
                    ("handleDeviceExtInputStatusChanged, invalid status: " + status)
                            + (" for: " + device));
        if (status != 0 && status != 1) {
            Log.e(TAG, logInfo + ": Invalid status argument");
            return;
        }

        boolean active = (status == 0x01);
        if (!input.setActive(id, active)) {
            Log.e(
                    TAG,
                    ("handleDeviceExtInputStatusChanged, error while setting inputId: " + id)
                            + ("for: " + device));
        }
        Log.d(TAG, logInfo);
        input.setStatus(id, status);
    }

    void handleDeviceExtInputTypeChanged(BluetoothDevice device, int id, int type) {
        Log.d(
                TAG,
                ("handleDeviceExtInputTypeChanged, device: " + device)
                        + (" inputId: " + id)
                        + (" type: " + type));
        String logInfo =
                "handleDeviceExtInputTypeChanged("
                        + ("device:" + device)
                        + (", id" + id)
                        + (", type" + type)
                        + ")";

        VolumeControlInputDescriptor input = mAudioInputs.get(device);
        if (input == null) {
            Log.e(
                    TAG,
                    ("handleDeviceExtInputTypeChanged, inputId: " + id)
                            + (" not found for device: " + device));
            Log.e(TAG, logInfo + ": This device has no audio input control");
            return;
        }

        if (!input.setType(id, type)) {
            Log.e(
                    TAG,
                    ("handleDeviceExtInputTypeChanged, error while setting inputId: " + id)
                            + ("for: " + device));
        if (type > 7) { // AudioInputType.AMBIENT) {
            Log.e(TAG, logInfo + ": Invalid type argument");
            return;
        }

        Log.d(TAG, logInfo);
        input.setType(id, type);
    }

    void handleDeviceExtInputDescriptionChanged(
            BluetoothDevice device, int id, String description) {
        Log.d(
                TAG,
                ("handleDeviceExtInputDescriptionChanged, device: " + device)
                        + (" inputId: " + id)
                        + (" description: " + description));
        String logInfo =
                "handleDeviceExtInputDescriptionChanged("
                        + ("device:" + device)
                        + (", id" + id)
                        + (", description" + description)
                        + ")";

        VolumeControlInputDescriptor input = mAudioInputs.get(device);
        if (input == null) {
            Log.e(
                    TAG,
                    ("handleDeviceExtInputDescriptionChanged, inputId: " + id)
                            + (" not found for device: " + device));
            Log.e(TAG, logInfo + ": This device has no audio input control");
            return;
        }

        if (!input.setDescription(id, description)) {
            Log.e(
                    TAG,
                    ("handleDeviceExtInputDescriptionChanged, error while setting inputId: " + id)
                            + ("for: " + device));
        if (description == null) {
            Log.e(TAG, logInfo + ": Invalid description argument");
            return;
        }

        Log.d(TAG, logInfo);
        input.setDescription(id, description);
    }

    void handleDeviceExtInputGainPropsChanged(
            BluetoothDevice device, int id, int unit, int min, int max) {
        Log.d(
                TAG,
                ("handleDeviceExtInputGainPropsChanged, device: " + device)
                        + (" inputId: " + id)
                        + (" unit: " + unit + " min" + min + " max:" + max));
        String logInfo =
                "handleDeviceExtInputGainPropsChanged("
                        + ("device:" + device)
                        + (", id" + id)
                        + (" unit: " + unit + " min" + min + " max:" + max)
                        + ")";

        VolumeControlInputDescriptor input = mAudioInputs.get(device);
        if (input == null) {
            Log.e(
                    TAG,
                    ("handleDeviceExtInputGainPropsChanged, inputId: " + id)
                            + (" not found for device: " + device));
            Log.e(TAG, logInfo + ": This device has no audio input control");
            return;
        }

        if (!input.setPropSettings(id, unit, min, max)) {
            Log.e(
                    TAG,
                    ("handleDeviceExtInputGainPropsChanged, error while setting inputId: " + id)
                            + ("for: " + device));
        }
        Log.d(TAG, logInfo);
        input.setPropSettings(id, unit, min, max);
    }

    void messageFromNative(VolumeControlStackEvent stackEvent) {
+115 −123

File changed.

Preview size limit exceeded, changes collapsed.