Revert "Hearing Aid Service Stub"
This reverts commit 06801a47fb65c132f9a923522f6b68c86c491d70.
Reason for revert: Service shutdown not working
Bug: 74511352
Bug: 69623109
Test: Manual
Change-Id: I54fccb1378a96656e7b4df2df3d9d96594499a9d
(cherry picked from commit 1799556b5cdee32119001e37dded728685c8b0cb)
(cherry picked from commit 8219c2d5c5e141407cf3d9fb29e5dbae12a91c75)
Change-Id: I855d1c4c058bab0a1b926a272e39b803471072a9
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ae36f1e..73a4154 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -382,14 +382,6 @@
<action android:name="android.bluetooth.IBluetoothPbapClient" />
</intent-filter>
</service>
- <service
- android:process="@string/process"
- android:name = ".hearingaid.HearingAidService"
- android:enabled="@bool/profile_supported_hearing_aid">
- <intent-filter>
- <action android:name="android.bluetooth.IBluetoothHearingAid" />
- </intent-filter>
- </service>
<!-- Authenticator for PBAP account. -->
<service
android:process="@string/process"
diff --git a/res/values/config.xml b/res/values/config.xml
index 1e5a03c..3595e56 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -31,7 +31,6 @@
<bool name="profile_supported_pbapclient">false</bool>
<bool name="profile_supported_mapmce">false</bool>
<bool name="profile_supported_hid_device">true</bool>
- <bool name="profile_supported_hearing_aid">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
diff --git a/src/com/android/bluetooth/btservice/Config.java b/src/com/android/bluetooth/btservice/Config.java
index fafd0bf..927c929 100644
--- a/src/com/android/bluetooth/btservice/Config.java
+++ b/src/com/android/bluetooth/btservice/Config.java
@@ -29,7 +29,6 @@
import com.android.bluetooth.avrcpcontroller.AvrcpControllerService;
import com.android.bluetooth.gatt.GattService;
import com.android.bluetooth.hdp.HealthService;
-import com.android.bluetooth.hearingaid.HearingAidService;
import com.android.bluetooth.hfp.HeadsetService;
import com.android.bluetooth.hfpclient.HeadsetClientService;
import com.android.bluetooth.hid.HidDeviceService;
@@ -95,9 +94,7 @@
new ProfileConfig(BluetoothOppService.class, R.bool.profile_supported_opp,
(1 << BluetoothProfile.OPP)),
new ProfileConfig(BluetoothPbapService.class, R.bool.profile_supported_pbap,
- (1 << BluetoothProfile.PBAP)),
- new ProfileConfig(HearingAidService.class, R.bool.profile_supported_hearing_aid,
- (1 << BluetoothProfile.HEARING_AID))
+ (1 << BluetoothProfile.PBAP))
};
private static Class[] sSupportedProfiles = new Class[0];
diff --git a/src/com/android/bluetooth/hearingaid/HearingAidService.java b/src/com/android/bluetooth/hearingaid/HearingAidService.java
deleted file mode 100644
index bbf3c8c..0000000
--- a/src/com/android/bluetooth/hearingaid/HearingAidService.java
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright 2018 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.bluetooth.hearingaid;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothCodecStatus;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHearingAid;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IBluetoothHearingAid;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.HandlerThread;
-import android.os.ParcelUuid;
-import android.provider.Settings;
-import android.support.annotation.VisibleForTesting;
-import android.util.Log;
-
-import com.android.bluetooth.Utils;
-import com.android.bluetooth.btservice.AdapterService;
-import com.android.bluetooth.btservice.ProfileService;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Provides Bluetooth HearingAid profile, as a service in the Bluetooth application.
- * @hide
- */
-public class HearingAidService extends ProfileService {
- private static final boolean DBG = true;
- private static final String TAG = "HearingAidService";
-
- private static HearingAidService sHearingAidService;
-
- private BluetoothAdapter mAdapter;
- private HandlerThread mStateMachinesThread;
-
- private BluetoothDevice mActiveDevice;
-
- private final Map<BluetoothDevice, Integer> mDeviceMap = new HashMap<>();
-
- private BroadcastReceiver mBondStateChangedReceiver;
- private BroadcastReceiver mConnectionStateChangedReceiver;
-
- @Override
- protected IProfileServiceBinder initBinder() {
- return new BluetoothHearingAidBinder(this);
- }
-
- @Override
- protected void create() {
- if (DBG) {
- Log.d(TAG, "create()");
- }
- }
-
- @Override
- protected boolean start() {
- if (DBG) {
- Log.d(TAG, "start()");
- }
- if (sHearingAidService != null) {
- throw new IllegalStateException("start() called twice");
- }
-
- // Step 1: Get BluetoothAdapter, AdapterService, A2dpNativeInterface, AudioManager.
- // None of them can be null.
- mAdapter = Objects.requireNonNull(BluetoothAdapter.getDefaultAdapter(),
- "BluetoothAdapter cannot be null when HearingAidService starts");
- mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(),
- "AdapterService cannot be null when HearingAidService starts");
- // TODO: Add native interface
-
- // Step 2: Start handler thread for state machines
- // TODO: Clear state machines
- mStateMachinesThread = new HandlerThread("HearingAidService.StateMachines");
- mStateMachinesThread.start();
-
- // Step 3: Initialize native interface
- // TODO: Init native interface
-
- // Step 4: Setup broadcast receivers
- IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
- mBondStateChangedReceiver = new BondStateChangedReceiver();
- registerReceiver(mBondStateChangedReceiver, filter);
- filter = new IntentFilter();
- filter.addAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
- mConnectionStateChangedReceiver = new ConnectionStateChangedReceiver();
- registerReceiver(mConnectionStateChangedReceiver, filter);
-
- // Step 5: Mark service as started
- setHearingAidService(this);
-
- // Step 6: Clear active device
- setActiveDevice(null);
-
- return true;
- }
-
- @Override
- protected boolean stop() {
- if (DBG) {
- Log.d(TAG, "stop()");
- }
- if (sHearingAidService == null) {
- Log.w(TAG, "stop() called before start()");
- return true;
- }
-
- // Step 6: Clear active device
- setActiveDevice(null);
-
- // Step 5: Mark service as stopped
- setHearingAidService(null);
-
- // Step 4: Unregister broadcast receivers
- unregisterReceiver(mBondStateChangedReceiver);
- mBondStateChangedReceiver = null;
- unregisterReceiver(mConnectionStateChangedReceiver);
- mConnectionStateChangedReceiver = null;
-
- // Step 3: Cleanup native interface
- // TODO: Cleanup native interface
-
- // Step 3: Destroy state machines and stop handler thread
- // TODO: Implement me
-
- if (mStateMachinesThread != null) {
- mStateMachinesThread.quitSafely();
- mStateMachinesThread = null;
- }
-
- // Step 1: Clear BluetoothAdapter, AdapterService, HearingAidNativeInterface
- // TODO: Set native interface to null
- mAdapterService = null;
- mAdapter = null;
-
- return true;
- }
-
- @Override
- protected void cleanup() {
- if (DBG) {
- Log.d(TAG, "cleanup()");
- }
- }
-
- /**
- * Get the HearingAidService instance
- * @return HearingAidService instance
- */
- public static synchronized HearingAidService getHearingAidService() {
- if (sHearingAidService == null) {
- Log.w(TAG, "getHearingAidService(): service is NULL");
- return null;
- }
-
- if (!sHearingAidService.isAvailable()) {
- Log.w(TAG, "getHearingAidService(): service is not available");
- return null;
- }
- return sHearingAidService;
- }
-
- private static synchronized void setHearingAidService(HearingAidService instance) {
- if (DBG) {
- Log.d(TAG, "setHearingAidService(): set to: " + instance);
- }
- sHearingAidService = instance;
- }
-
- boolean connect(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
- if (DBG) {
- Log.d(TAG, "connect(): " + device);
- }
-
- if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) {
- return false;
- }
- ParcelUuid[] featureUuids = device.getUuids();
- if (!BluetoothUuid.isUuidPresent(featureUuids, BluetoothUuid.HearingAid)) {
- Log.e(TAG, "Cannot connect to " + device + " : Remote does not have HearingAid UUID");
- return false;
- }
-
- // TODO: Implement me
- return false;
- }
-
- boolean disconnect(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
- if (DBG) {
- Log.d(TAG, "disconnect(): " + device);
- }
-
- // TODO: Implement me
- return false;
- }
-
- List<BluetoothDevice> getConnectedDevices() {
- enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- // TODO: Implement me
- return new ArrayList<>();
- }
-
- /**
- * Check whether can connect to a peer device.
- * The check considers a number of factors during the evaluation.
- *
- * @param device the peer device to connect to
- * @return true if connection is allowed, otherwise false
- */
- boolean okToConnect(BluetoothDevice device) {
- throw new IllegalStateException("Implement me");
- }
-
- List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
- enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- // TODO: Implement me
- return new ArrayList<>();
- }
-
- /**
- * Get the list of devices that have state machines.
- *
- * @return the list of devices that have state machines
- */
- @VisibleForTesting
- List<BluetoothDevice> getDevices() {
- // TODO: Implement me
- return new ArrayList<>();
- }
-
- int getConnectionState(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- // TODO: Implement me
- return BluetoothProfile.STATE_DISCONNECTED;
- }
-
- /**
- * Set the active device.
- *
- * @param device the active device
- * @return true on success, otherwise false
- */
- public synchronized boolean setActiveDevice(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
- // TODO: Implement me
- return false;
- }
-
- /**
- * Get the active device.
- *
- * @return the active device or null if no device is active
- */
- public synchronized BluetoothDevice getActiveDevice() {
- enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- throw new IllegalStateException("Implement me");
- }
-
- private synchronized boolean isActiveDevice(BluetoothDevice device) {
- throw new IllegalStateException("Implement me");
- }
-
- /**
- * Set the priority of the Hearing Aid profile.
- *
- * @param device the remote device
- * @param priority the priority of the profile
- * @return true on success, otherwise false
- */
- public boolean setPriority(BluetoothDevice device, int priority) {
- enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission");
- Settings.Global.putInt(getContentResolver(),
- Settings.Global.getBluetoothHearingAidPriorityKey(device.getAddress()), priority);
- if (DBG) {
- Log.d(TAG, "Saved priority " + device + " = " + priority);
- }
- return true;
- }
- /**
- * Get the priority of the Hearing Aid profile.
- *
- * @param device the remote device
- * @return the profile priority
- */
- public int getPriority(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission");
- int priority = Settings.Global.getInt(getContentResolver(),
- Settings.Global.getBluetoothHearingAidPriorityKey(device.getAddress()),
- BluetoothProfile.PRIORITY_UNDEFINED);
- return priority;
- }
-
- synchronized boolean isHearingAidPlaying(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- if (DBG) {
- Log.d(TAG, "isHearingAidPlaying(" + device + ")");
- }
- throw new IllegalStateException("Implement me");
- }
-
- /**
- * Gets the current codec status (configuration and capability).
- *
- * @param device the remote Bluetooth device. If null, use the currect
- * active HearingAid Bluetooth device.
- * @return the current codec status
- * @hide
- */
- public BluetoothCodecStatus getCodecStatus(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- if (DBG) {
- Log.d(TAG, "getCodecStatus(" + device + ")");
- }
- throw new IllegalStateException("Implement me");
- }
-
- private void broadcastActiveDevice(BluetoothDevice device) {
- if (DBG) {
- Log.d(TAG, "broadcastActiveDevice(" + device + ")");
- }
-
- Intent intent = new Intent(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
- | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
- }
-
- // Remove state machine if the bonding for a device is removed
- private class BondStateChangedReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) {
- return;
- }
- int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
- BluetoothDevice.ERROR);
- BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- if (DBG) {
- Log.d(TAG, "Bond state changed for device: " + device + " state: " + state);
- }
- if (state != BluetoothDevice.BOND_NONE) {
- return;
- }
- // TODO: Implement me
- }
- }
-
- /**
- * Process a change in the bonding state for a device.
- *
- * @param device the device whose bonding state has changed
- * @param bondState the new bond state for the device. Possible values are:
- * {@link BluetoothDevice#BOND_NONE},
- * {@link BluetoothDevice#BOND_BONDING},
- * {@link BluetoothDevice#BOND_BONDED}.
- */
- @VisibleForTesting
- void bondStateChanged(BluetoothDevice device, int bondState) {
- if (DBG) {
- Log.d(TAG, "Bond state changed for device: " + device + " state: " + bondState);
- }
- // Remove state machine if the bonding for a device is removed
- if (bondState != BluetoothDevice.BOND_NONE) {
- return;
- }
- // TODO: Implement me
- }
-
- private synchronized void connectionStateChanged(BluetoothDevice device, int fromState,
- int toState) {
- // TODO: Implement me
- }
-
- private class ConnectionStateChangedReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
- return;
- }
- BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- int toState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
- int fromState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1);
- connectionStateChanged(device, fromState, toState);
- }
- }
-
- // Binder object: Must be static class or memory leak may occur
- @VisibleForTesting
- static class BluetoothHearingAidBinder extends IBluetoothHearingAid.Stub
- implements IProfileServiceBinder {
- private HearingAidService mService;
-
- private HearingAidService getService() {
- if (!Utils.checkCaller()) {
- Log.w(TAG, "HearingAid call not allowed for non-active user");
- return null;
- }
-
- if (mService != null && mService.isAvailable()) {
- return mService;
- }
- return null;
- }
-
- BluetoothHearingAidBinder(HearingAidService svc) {
- mService = svc;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @Override
- public boolean connect(BluetoothDevice device) {
- HearingAidService service = getService();
- if (service == null) {
- return false;
- }
- return service.connect(device);
- }
-
- @Override
- public boolean disconnect(BluetoothDevice device) {
- HearingAidService service = getService();
- if (service == null) {
- return false;
- }
- return service.disconnect(device);
- }
-
- @Override
- public List<BluetoothDevice> getConnectedDevices() {
- HearingAidService service = getService();
- if (service == null) {
- return new ArrayList<BluetoothDevice>(0);
- }
- return service.getConnectedDevices();
- }
-
- @Override
- public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
- HearingAidService service = getService();
- if (service == null) {
- return new ArrayList<BluetoothDevice>(0);
- }
- return service.getDevicesMatchingConnectionStates(states);
- }
-
- @Override
- public int getConnectionState(BluetoothDevice device) {
- HearingAidService service = getService();
- if (service == null) {
- return BluetoothProfile.STATE_DISCONNECTED;
- }
- return service.getConnectionState(device);
- }
-
- @Override
- public boolean setPriority(BluetoothDevice device, int priority) {
- HearingAidService service = getService();
- if (service == null) {
- return false;
- }
- return service.setPriority(device, priority);
- }
-
- @Override
- public int getPriority(BluetoothDevice device) {
- HearingAidService service = getService();
- if (service == null) {
- return BluetoothProfile.PRIORITY_UNDEFINED;
- }
- return service.getPriority(device);
- }
-
- @Override
- public void setVolume(int volume) {
- // TODO: Implement me
- }
-
- @Override
- public void adjustVolume(int direction) {
- // TODO: Implement me
- }
-
- @Override
- public int getVolume() {
- return 0;
- }
-
- @Override
- public long getHiSyncId(BluetoothDevice device) {
- return 0;
- }
-
- @Override
- public int getDeviceSide(BluetoothDevice device) {
- return 0;
- }
-
- @Override
- public int getDeviceMode(BluetoothDevice device) {
- return 0;
- }
- }
-
- @Override
- public void dump(StringBuilder sb) {
- super.dump(sb);
- ProfileService.println(sb, "mActiveDevice: " + mActiveDevice);
- }
-}