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

Commit c879f7ed authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge " MAP: Fix service shutdown procedure"

parents 0258e735 fc35896b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -396,7 +396,7 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler {
        return (mConnSocket != null);
    }

    public void shutdown() {
    public synchronized void shutdown() {
        if (D) Log.d(TAG, "MAP Service shutdown");

        if (mServerSession != null) {
+54 −10
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelUuid;
import android.os.PowerManager;
@@ -50,6 +52,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;

public class BluetoothMapService extends ProfileService {
    private static final String TAG = "BluetoothMapService";
@@ -65,7 +68,6 @@ public class BluetoothMapService extends ProfileService {
    public static final boolean DEBUG = true; //FIXME set to false;
    public static boolean VERBOSE = Log.isLoggable(LOG_TAG, Log.VERBOSE);


    /**
     * Intent indicating timeout for user confirmation, which is sent to
     * BluetoothMapActivity
@@ -146,6 +148,7 @@ public class BluetoothMapService extends ProfileService {
    private boolean mAccountChanged = false;
    private boolean mSdpSearchInitiated = false;
    SdpMnsRecord mMnsRecord = null;
    private MapServiceMessageHandler mSessionStatusHandler;

    // package and class name to which we send intent to check phone book access permission
    private static final String ACCESS_AUTHORITY_PACKAGE = "com.android.settings";
@@ -163,7 +166,7 @@ public class BluetoothMapService extends ProfileService {
    }


    private final void closeService() {
    private synchronized void closeService(CountDownLatch latch) {
        if (DEBUG) Log.d(TAG, "MAP Service closeService in");

        if (mBluetoothMnsObexClient != null) {
@@ -192,6 +195,9 @@ public class BluetoothMapService extends ProfileService {
        mRemoteDevice = null;

        if (VERBOSE) Log.v(TAG, "MAP Service closeService out");
        if(latch != null) {
            latch.countDown();
        }
    }

    /**
@@ -317,7 +323,10 @@ public class BluetoothMapService extends ProfileService {
        }
    }

    private final Handler mSessionStatusHandler = new Handler() {
    private final class MapServiceMessageHandler extends Handler {
        private MapServiceMessageHandler(Looper looper) {
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
            if (DEBUG) Log.v(TAG, "Handler(): got msg=" + msg.what);
@@ -369,7 +378,8 @@ public class BluetoothMapService extends ProfileService {
                case SHUTDOWN:
                    /* Ensure to call close from this handler to avoid starting new stuff
                       because of pending messages */
                    closeService();
                    CountDownLatch latch = (CountDownLatch) msg.obj;
                    closeService(latch);
                    break;
                case MSG_ACQUIRE_WAKE_LOCK:
                    if (VERBOSE) Log.v(TAG, "Acquire Wake Lock request message");
@@ -580,6 +590,12 @@ public class BluetoothMapService extends ProfileService {
        }

        if (VERBOSE) Log.v(TAG, "verbose logging is enabled");

        HandlerThread thread = new HandlerThread("BluetoothMapHandler");
        thread.start();
        Looper looper = thread.getLooper();
        mSessionStatusHandler = new MapServiceMessageHandler(looper);

        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
@@ -775,9 +791,26 @@ public class BluetoothMapService extends ProfileService {
        } catch (Exception e) {
            Log.w(TAG,"Unable to unregister map receiver",e);
        }

        CountDownLatch latch = new CountDownLatch(1);
        sendShutdownMessage(latch);
        // We need to wait for shutdown to complete to avoid being garbage collected before
        // shutdown completes.
        if(DEBUG) Log.i(TAG, "Waiting for shutdown to complete");
        try {
            latch.await();
        } catch (InterruptedException e) {
            Log.e(TAG, "Interrupt received while waiting for shutdown to complete", e);
        }
        if (mSessionStatusHandler != null) {
            mSessionStatusHandler.removeCallbacksAndMessages(null);
            Looper looper = mSessionStatusHandler.getLooper();
            if (looper != null) {
                looper.quit();
            }
            mSessionStatusHandler = null;
        }
        setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED);
        sendShutdownMessage();
        if (VERBOSE) Log.d(TAG, "stop() out");
        return true;
    }

@@ -785,7 +818,7 @@ public class BluetoothMapService extends ProfileService {
        if (DEBUG) Log.d(TAG, "cleanup()");
        setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED);
        // TODO: Change to use message? - do we need to wait for completion?
        closeService();
        closeService(null); // Stop() should be called to handle cleanup - hence this is not needed
        return true;
    }

@@ -911,7 +944,7 @@ public class BluetoothMapService extends ProfileService {
        } // Can only be null during shutdown
    }

    private void sendShutdownMessage() {
    private void sendShutdownMessage(CountDownLatch latch) {
        /* Any pending messages are no longer valid.
        To speed up things, simply delete them. */
        if (mRemoveTimeoutMsg) {
@@ -923,7 +956,18 @@ public class BluetoothMapService extends ProfileService {
        }
        mSessionStatusHandler.removeCallbacksAndMessages(null);
        // Request release of all resources
        mSessionStatusHandler.obtainMessage(SHUTDOWN).sendToTarget();
        Message msg = mSessionStatusHandler.obtainMessage(SHUTDOWN,latch);
        if( mSessionStatusHandler.sendMessage(msg) == false) {
            /* most likely caused by shutdown being called from multiple sources - e.g.BT off
             * signaled through intent and a service shutdown simultaneously.
             * Intended behavior not documented, hence we need to be able to handle all cases. */
            Log.e(TAG, "mSessionStatusHandler.sendMessage() failed trigger latch locally");
            if(latch != null) {
                latch.countDown();
            }
        } else {
            if(DEBUG) Log.e(TAG, "mSessionStatusHandler.sendMessage() dispatched shutdown message");
        }
    }

    private MapBroadcastReceiver mMapReceiver = new MapBroadcastReceiver();
@@ -939,7 +983,7 @@ public class BluetoothMapService extends ProfileService {
                                               BluetoothAdapter.ERROR);
                if (state == BluetoothAdapter.STATE_TURNING_OFF) {
                    if (DEBUG) Log.d(TAG, "STATE_TURNING_OFF");
                    sendShutdownMessage();
                    sendShutdownMessage(null);
                } else if (state == BluetoothAdapter.STATE_ON) {
                    if (DEBUG) Log.d(TAG, "STATE_ON");
                    // start ServerSocket listener threads