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);
-    }
-}