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

Commit 555794fd authored by Łukasz Rymanowski's avatar Łukasz Rymanowski Committed by Jakub Pawlowski
Browse files

csip: Add Coordinated Set Identification Profile boilerplate

Implementation will be provided in the upcoming patch.

Tag: #feature
Test: compilation
Bug: 150670922
Sponsor: jpawlowski@
Merged-In: I85f4edbed9d1791fccfc6e73453a5432e0186f44
Change-Id: I85f4edbed9d1791fccfc6e73453a5432e0186f44
parent 7d644700
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -434,6 +434,15 @@
                <action android:name="android.bluetooth.IBluetoothLeAudio" />
            </intent-filter>
        </service>
        <service
            android:process="@string/process"
            android:name = ".csip.CsipSetCoordinatorService"
            android:enabled="@bool/profile_supported_csip_set_coordinator"
            android:exported = "true">
            <intent-filter>
                <action android:name="android.bluetooth.IBluetoothCsipSetCoordinator" />
            </intent-filter>
        </service>
        <!-- Authenticator for PBAP account. -->
        <service android:process="@string/process"
             android:name=".pbapclient.AuthenticationService"
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
    <bool name="profile_supported_le_audio">true</bool>
    <bool name="profile_supported_vc">true</bool>
    <bool name="profile_supported_mcp_server">true</bool>
    <bool name="profile_supported_csip_set_coordinator">true</bool>

    <!-- If true, we will require location to be enabled on the device to
         fire Bluetooth LE scan result callbacks in addition to having one
+5 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.bluetooth.a2dp.A2dpService;
import com.android.bluetooth.a2dpsink.A2dpSinkService;
import com.android.bluetooth.avrcp.AvrcpTargetService;
import com.android.bluetooth.avrcpcontroller.AvrcpControllerService;
import com.android.bluetooth.csip.CsipSetCoordinatorService;
import com.android.bluetooth.gatt.GattService;
import com.android.bluetooth.hearingaid.HearingAidService;
import com.android.bluetooth.hfp.HeadsetService;
@@ -112,7 +113,10 @@ public class Config {
                    (1 << BluetoothProfile.MCP_SERVER)),
            new ProfileConfig(HearingAidService.class,
                    com.android.internal.R.bool.config_hearing_aid_profile_supported,
                    (1 << BluetoothProfile.HEARING_AID))
                    (1 << BluetoothProfile.HEARING_AID)),
            new ProfileConfig(CsipSetCoordinatorService.class,
                    R.bool.profile_supported_csip_set_coordinator,
                    (1 << BluetoothProfile.CSIP_SET_COORDINATOR)),
    };

    private static Class[] sSupportedProfiles = new Class[0];
+267 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 HIMSA II K/S - www.himsa.com.
 * Represented by EHIMA - www.ehima.com
 *
 * 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.bluetooth.csip;

import android.annotation.NonNull;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.IBluetoothCsipSetCoordinator;
import android.bluetooth.IBluetoothCsipSetCoordinatorLockCallback;
import android.os.ParcelUuid;
import android.util.Log;

import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.ProfileService;
import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Provides Bluetooth CSIP Set Coordinator profile, as a service.
 * @hide
 */
public class CsipSetCoordinatorService extends ProfileService {
    private static final boolean DBG = false;
    private static final String TAG = "CsipSetCoordinatorService";

    private static CsipSetCoordinatorService sCsipSetCoordinatorService;

    @Override
    protected IProfileServiceBinder initBinder() {
        return new BluetoothCsisBinder(this);
    }

    @Override
    protected void create() {
        if (DBG) {
            Log.d(TAG, "create()");
        }
    }

    @Override
    protected boolean start() {
        if (DBG) {
            Log.d(TAG, "start()");
        }
        if (sCsipSetCoordinatorService != null) {
            throw new IllegalStateException("start() called twice");
        }

        // Mark service as started
        setCsipSetCoordinatorService(this);

        return true;
    }

    @Override
    protected boolean stop() {
        if (DBG) {
            Log.d(TAG, "stop()");
        }
        if (sCsipSetCoordinatorService == null) {
            Log.w(TAG, "stop() called before start()");
            return true;
        }

        // Mark service as stopped
        setCsipSetCoordinatorService(null);

        return true;
    }

    @Override
    protected void cleanup() {
        if (DBG) {
            Log.d(TAG, "cleanup()");
        }
    }

    /**
     * Get the CsipSetCoordinatorService instance
     * @return CsipSetCoordinatorService instance
     */
    public static synchronized CsipSetCoordinatorService getCsipSetCoordinatorService() {
        if (sCsipSetCoordinatorService == null) {
            Log.w(TAG, "getCsipSetCoordinatorService(): service is NULL");
            return null;
        }

        if (!sCsipSetCoordinatorService.isAvailable()) {
            Log.w(TAG, "getCsipSetCoordinatorService(): service is not available");
            return null;
        }
        return sCsipSetCoordinatorService;
    }

    private static synchronized void setCsipSetCoordinatorService(
            CsipSetCoordinatorService instance) {
        if (DBG) {
            Log.d(TAG, "setCsipSetCoordinatorService(): set to: " + instance);
        }
        sCsipSetCoordinatorService = instance;
    }

    /**
     * Binder object: must be a static class or memory leak may occur
     */
    @VisibleForTesting
    static class BluetoothCsisBinder
            extends IBluetoothCsipSetCoordinator.Stub implements IProfileServiceBinder {
        private CsipSetCoordinatorService mService;

        private CsipSetCoordinatorService getService() {
            if (!Utils.checkCaller()) {
                Log.w(TAG, "CSIS call not allowed for non-active user");
                return null;
            }

            if (mService != null && mService.isAvailable()) {
                return mService;
            }
            return null;
        }

        BluetoothCsisBinder(CsipSetCoordinatorService svc) {
            mService = svc;
        }

        @Override
        public void cleanup() {
            mService = null;
        }

        @Override
        public boolean connect(BluetoothDevice device) {
            CsipSetCoordinatorService service = getService();
            if (service == null) {
                return false;
            }
            return false;
        }

        @Override
        public boolean disconnect(BluetoothDevice device) {
            CsipSetCoordinatorService service = getService();
            if (service == null) {
                return false;
            }
            return false;
        }

        @Override
        public List<BluetoothDevice> getConnectedDevices() {
            CsipSetCoordinatorService service = getService();
            if (service == null) {
                return new ArrayList<>();
            }
            return new ArrayList<>();
        }

        @Override
        public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
            CsipSetCoordinatorService service = getService();
            if (service == null) {
                return new ArrayList<>();
            }
            return new ArrayList<>();
        }

        @Override
        public int getConnectionState(BluetoothDevice device) {
            CsipSetCoordinatorService service = getService();
            if (service == null) {
                return BluetoothProfile.STATE_DISCONNECTED;
            }
            return BluetoothProfile.STATE_DISCONNECTED;
        }

        @Override
        public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) {
            CsipSetCoordinatorService service = getService();
            if (service == null) {
                return false;
            }
            return false;
        }

        @Override
        public int getConnectionPolicy(BluetoothDevice device) {
            CsipSetCoordinatorService service = getService();
            if (service == null) {
                return BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
            }
            return BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
        }

        @Override
        public ParcelUuid groupLock(
                int groupId, @NonNull IBluetoothCsipSetCoordinatorLockCallback callback) {
            CsipSetCoordinatorService service = getService();
            if (service == null) {
                return null;
            }

            return null;
        }

        @Override
        public void groupUnlock(@NonNull ParcelUuid lockUuid) {
            CsipSetCoordinatorService service = getService();
            if (service == null) {
                return;
            }
        }

        @Override
        public List<Integer> getAllGroupIds(ParcelUuid uuid) {
            CsipSetCoordinatorService service = getService();
            if (service == null) {
                return new ArrayList<Integer>();
            }

            return new ArrayList<Integer>();
        }

        @Override
        public Map<Integer, ParcelUuid> getGroupUuidMapByDevice(BluetoothDevice device) {
            CsipSetCoordinatorService service = getService();
            if (service == null) {
                return null;
            }

            return null;
        }

        @Override
        public int getDesiredGroupSize(int groupId) {
            CsipSetCoordinatorService service = getService();
            if (service == null) {
                return IBluetoothCsipSetCoordinator.CSIS_GROUP_SIZE_UNKNOWN;
            }

            return IBluetoothCsipSetCoordinator.CSIS_GROUP_SIZE_UNKNOWN;
        }
    }

    @Override
    public void dump(StringBuilder sb) {
        super.dump(sb);
    }
}