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

Commit 8f43d3ea authored by Ugo Yu's avatar Ugo Yu Committed by android-build-merger
Browse files

Merge "Fix binder leakage when turning off Bluetooth"

am: 50269bef43

Change-Id: I17b81361793054f21723f8cab00b3c6fb2a2b615
parents da2026bb 1652b94a
Loading
Loading
Loading
Loading
+86 −227
Original line number Diff line number Diff line
@@ -22,23 +22,16 @@ import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;


/**
@@ -209,43 +202,13 @@ public final class BluetoothA2dp implements BluetoothProfile {
    @UnsupportedAppUsage
    public static final int OPTIONAL_CODECS_PREF_ENABLED = 1;

    private Context mContext;
    private ServiceListener mServiceListener;
    private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
    @GuardedBy("mServiceLock")
    private IBluetoothA2dp mService;
    private BluetoothAdapter mAdapter;

    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
            new IBluetoothStateChangeCallback.Stub() {
                public void onBluetoothStateChange(boolean up) {
                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
                    if (!up) {
                        if (VDBG) Log.d(TAG, "Unbinding service...");
                        try {
                            mServiceLock.writeLock().lock();
                            if (mService != null) {
                                mService = null;
                                mContext.unbindService(mConnection);
                            }
                        } catch (Exception re) {
                            Log.e(TAG, "", re);
                        } finally {
                            mServiceLock.writeLock().unlock();
                        }
                    } else {
                        try {
                            mServiceLock.readLock().lock();
                            if (mService == null) {
                                if (VDBG) Log.d(TAG, "Binding service...");
                                doBind();
                            }
                        } catch (Exception re) {
                            Log.e(TAG, "", re);
                        } finally {
                            mServiceLock.readLock().unlock();
                        }
                    }
    private final BluetoothProfileConnector<IBluetoothA2dp> mProfileConnector =
            new BluetoothProfileConnector(this, BluetoothProfile.A2DP, "BluetoothA2dp",
                    IBluetoothA2dp.class.getName()) {
                @Override
                public IBluetoothA2dp getServiceInterface(IBinder service) {
                    return IBluetoothA2dp.Stub.asInterface(Binder.allowBlocking(service));
                }
    };

@@ -253,57 +216,18 @@ public final class BluetoothA2dp implements BluetoothProfile {
     * Create a BluetoothA2dp proxy object for interacting with the local
     * Bluetooth A2DP service.
     */
    /*package*/ BluetoothA2dp(Context context, ServiceListener l) {
        mContext = context;
        mServiceListener = l;
    /*package*/ BluetoothA2dp(Context context, ServiceListener listener) {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        IBluetoothManager mgr = mAdapter.getBluetoothManager();
        if (mgr != null) {
            try {
                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
            } catch (RemoteException e) {
                Log.e(TAG, "", e);
            }
        }

        doBind();
    }

    boolean doBind() {
        Intent intent = new Intent(IBluetoothA2dp.class.getName());
        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
        intent.setComponent(comp);
        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
                UserHandle.CURRENT_OR_SELF)) {
            Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent);
            return false;
        }
        return true;
        mProfileConnector.connect(context, listener);
    }

    @UnsupportedAppUsage
    /*package*/ void close() {
        mServiceListener = null;
        IBluetoothManager mgr = mAdapter.getBluetoothManager();
        if (mgr != null) {
            try {
                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
            } catch (Exception e) {
                Log.e(TAG, "", e);
            }
        mProfileConnector.disconnect();
    }

        try {
            mServiceLock.writeLock().lock();
            if (mService != null) {
                mService = null;
                mContext.unbindService(mConnection);
            }
        } catch (Exception re) {
            Log.e(TAG, "", re);
        } finally {
            mServiceLock.writeLock().unlock();
        }
    private IBluetoothA2dp getService() {
        return mProfileConnector.getService();
    }

    @Override
@@ -333,17 +257,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
    public boolean connect(BluetoothDevice device) {
        if (DBG) log("connect(" + device + ")");
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled() && isValidDevice(device)) {
                return mService.connect(device);
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled() && isValidDevice(device)) {
                return service.connect(device);
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return false;
        } catch (RemoteException e) {
            Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
            return false;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -376,17 +298,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
    public boolean disconnect(BluetoothDevice device) {
        if (DBG) log("disconnect(" + device + ")");
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled() && isValidDevice(device)) {
                return mService.disconnect(device);
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled() && isValidDevice(device)) {
                return service.disconnect(device);
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return false;
        } catch (RemoteException e) {
            Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
            return false;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -397,17 +317,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
    public List<BluetoothDevice> getConnectedDevices() {
        if (VDBG) log("getConnectedDevices()");
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()) {
                return mService.getConnectedDevices();
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()) {
                return service.getConnectedDevices();
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return new ArrayList<BluetoothDevice>();
        } catch (RemoteException e) {
            Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
            return new ArrayList<BluetoothDevice>();
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -418,17 +336,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
        if (VDBG) log("getDevicesMatchingStates()");
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()) {
                return mService.getDevicesMatchingConnectionStates(states);
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()) {
                return service.getDevicesMatchingConnectionStates(states);
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return new ArrayList<BluetoothDevice>();
        } catch (RemoteException e) {
            Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
            return new ArrayList<BluetoothDevice>();
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -439,18 +355,16 @@ public final class BluetoothA2dp implements BluetoothProfile {
    public int getConnectionState(BluetoothDevice device) {
        if (VDBG) log("getState(" + device + ")");
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()
                    && isValidDevice(device)) {
                return mService.getConnectionState(device);
                return service.getConnectionState(device);
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return BluetoothProfile.STATE_DISCONNECTED;
        } catch (RemoteException e) {
            Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
            return BluetoothProfile.STATE_DISCONNECTED;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -480,18 +394,16 @@ public final class BluetoothA2dp implements BluetoothProfile {
    public boolean setActiveDevice(@Nullable BluetoothDevice device) {
        if (DBG) log("setActiveDevice(" + device + ")");
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()
                    && ((device == null) || isValidDevice(device))) {
                return mService.setActiveDevice(device);
                return service.setActiveDevice(device);
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return false;
        } catch (RemoteException e) {
            Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
            return false;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -511,17 +423,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
    public BluetoothDevice getActiveDevice() {
        if (VDBG) log("getActiveDevice()");
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()) {
                return mService.getActiveDevice();
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()) {
                return service.getActiveDevice();
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return null;
        } catch (RemoteException e) {
            Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
            return null;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -543,22 +453,20 @@ public final class BluetoothA2dp implements BluetoothProfile {
    public boolean setPriority(BluetoothDevice device, int priority) {
        if (DBG) log("setPriority(" + device + ", " + priority + ")");
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()
                    && isValidDevice(device)) {
                if (priority != BluetoothProfile.PRIORITY_OFF
                        && priority != BluetoothProfile.PRIORITY_ON) {
                    return false;
                }
                return mService.setPriority(device, priority);
                return service.setPriority(device, priority);
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return false;
        } catch (RemoteException e) {
            Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
            return false;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -578,18 +486,16 @@ public final class BluetoothA2dp implements BluetoothProfile {
    public int getPriority(BluetoothDevice device) {
        if (VDBG) log("getPriority(" + device + ")");
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()
                    && isValidDevice(device)) {
                return mService.getPriority(device);
                return service.getPriority(device);
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return BluetoothProfile.PRIORITY_OFF;
        } catch (RemoteException e) {
            Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
            return BluetoothProfile.PRIORITY_OFF;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -602,17 +508,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
    public boolean isAvrcpAbsoluteVolumeSupported() {
        if (DBG) Log.d(TAG, "isAvrcpAbsoluteVolumeSupported");
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()) {
                return mService.isAvrcpAbsoluteVolumeSupported();
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()) {
                return service.isAvrcpAbsoluteVolumeSupported();
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return false;
        } catch (RemoteException e) {
            Log.e(TAG, "Error talking to BT service in isAvrcpAbsoluteVolumeSupported()", e);
            return false;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -625,15 +529,13 @@ public final class BluetoothA2dp implements BluetoothProfile {
    public void setAvrcpAbsoluteVolume(int volume) {
        if (DBG) Log.d(TAG, "setAvrcpAbsoluteVolume");
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()) {
                mService.setAvrcpAbsoluteVolume(volume);
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()) {
                service.setAvrcpAbsoluteVolume(volume);
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
        } catch (RemoteException e) {
            Log.e(TAG, "Error talking to BT service in setAvrcpAbsoluteVolume()", e);
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -646,18 +548,16 @@ public final class BluetoothA2dp implements BluetoothProfile {
     */
    public boolean isA2dpPlaying(BluetoothDevice device) {
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()
                    && isValidDevice(device)) {
                return mService.isA2dpPlaying(device);
                return service.isA2dpPlaying(device);
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return false;
        } catch (RemoteException e) {
            Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
            return false;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -694,19 +594,17 @@ public final class BluetoothA2dp implements BluetoothProfile {
    public BluetoothCodecStatus getCodecStatus(BluetoothDevice device) {
        if (DBG) Log.d(TAG, "getCodecStatus(" + device + ")");
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()) {
                return mService.getCodecStatus(device);
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()) {
                return service.getCodecStatus(device);
            }
            if (mService == null) {
            if (service == null) {
                Log.w(TAG, "Proxy not attached to service");
            }
            return null;
        } catch (RemoteException e) {
            Log.e(TAG, "Error talking to BT service in getCodecStatus()", e);
            return null;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -723,17 +621,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
                                         BluetoothCodecConfig codecConfig) {
        if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")");
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()) {
                mService.setCodecConfigPreference(device, codecConfig);
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()) {
                service.setCodecConfigPreference(device, codecConfig);
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return;
        } catch (RemoteException e) {
            Log.e(TAG, "Error talking to BT service in setCodecConfigPreference()", e);
            return;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -772,21 +668,19 @@ public final class BluetoothA2dp implements BluetoothProfile {
     */
    private void enableDisableOptionalCodecs(BluetoothDevice device, boolean enable) {
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()) {
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()) {
                if (enable) {
                    mService.enableOptionalCodecs(device);
                    service.enableOptionalCodecs(device);
                } else {
                    mService.disableOptionalCodecs(device);
                    service.disableOptionalCodecs(device);
                }
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return;
        } catch (RemoteException e) {
            Log.e(TAG, "Error talking to BT service in enableDisableOptionalCodecs()", e);
            return;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -801,17 +695,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
    @UnsupportedAppUsage
    public int supportsOptionalCodecs(BluetoothDevice device) {
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled() && isValidDevice(device)) {
                return mService.supportsOptionalCodecs(device);
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled() && isValidDevice(device)) {
                return service.supportsOptionalCodecs(device);
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return OPTIONAL_CODECS_SUPPORT_UNKNOWN;
        } catch (RemoteException e) {
            Log.e(TAG, "Error talking to BT service in getSupportsOptionalCodecs()", e);
            return OPTIONAL_CODECS_SUPPORT_UNKNOWN;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -826,17 +718,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
    @UnsupportedAppUsage
    public int getOptionalCodecsEnabled(BluetoothDevice device) {
        try {
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled() && isValidDevice(device)) {
                return mService.getOptionalCodecsEnabled(device);
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled() && isValidDevice(device)) {
                return service.getOptionalCodecsEnabled(device);
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return OPTIONAL_CODECS_PREF_UNKNOWN;
        } catch (RemoteException e) {
            Log.e(TAG, "Error talking to BT service in getSupportsOptionalCodecs()", e);
            return OPTIONAL_CODECS_PREF_UNKNOWN;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -858,18 +748,16 @@ public final class BluetoothA2dp implements BluetoothProfile {
                Log.e(TAG, "Invalid value passed to setOptionalCodecsEnabled: " + value);
                return;
            }
            mServiceLock.readLock().lock();
            if (mService != null && isEnabled()
            final IBluetoothA2dp service = getService();
            if (service != null && isEnabled()
                    && isValidDevice(device)) {
                mService.setOptionalCodecsEnabled(device, value);
                service.setOptionalCodecsEnabled(device, value);
            }
            if (mService == null) Log.w(TAG, "Proxy not attached to service");
            if (service == null) Log.w(TAG, "Proxy not attached to service");
            return;
        } catch (RemoteException e) {
            Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
            return;
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

@@ -900,35 +788,6 @@ public final class BluetoothA2dp implements BluetoothProfile {
        }
    }

    private final ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            if (DBG) Log.d(TAG, "Proxy object connected");
            try {
                mServiceLock.writeLock().lock();
                mService = IBluetoothA2dp.Stub.asInterface(Binder.allowBlocking(service));
            } finally {
                mServiceLock.writeLock().unlock();
            }

            if (mServiceListener != null) {
                mServiceListener.onServiceConnected(BluetoothProfile.A2DP, BluetoothA2dp.this);
            }
        }

        public void onServiceDisconnected(ComponentName className) {
            if (DBG) Log.d(TAG, "Proxy object disconnected");
            try {
                mServiceLock.writeLock().lock();
                mService = null;
            } finally {
                mServiceLock.writeLock().unlock();
            }
            if (mServiceListener != null) {
                mServiceListener.onServiceDisconnected(BluetoothProfile.A2DP);
            }
        }
    };

    private boolean isEnabled() {
        if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
        return false;
+22 −106

File changed.

Preview size limit exceeded, changes collapsed.

+26 −103

File changed.

Preview size limit exceeded, changes collapsed.

+19 −21
Original line number Diff line number Diff line
@@ -337,20 +337,10 @@ public final class BluetoothHeadset implements BluetoothProfile {
                public void onBluetoothStateChange(boolean up) {
                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
                    if (!up) {
                        if (VDBG) Log.d(TAG, "Unbinding service...");
                        doUnbind();
                    } else {
                        synchronized (mConnection) {
                            try {
                                if (mService == null) {
                                    if (VDBG) Log.d(TAG, "Binding service...");
                        doBind();
                    }
                            } catch (Exception re) {
                                Log.e(TAG, "", re);
                            }
                        }
                    }
                }
            };

@@ -374,24 +364,32 @@ public final class BluetoothHeadset implements BluetoothProfile {
        doBind();
    }

    boolean doBind() {
    private boolean doBind() {
        synchronized (mConnection) {
            if (mService == null) {
                if (VDBG) Log.d(TAG, "Binding service...");
                try {
                    return mAdapter.getBluetoothManager().bindBluetoothProfileService(
                            BluetoothProfile.HEADSET, mConnection);
                } catch (RemoteException e) {
                    Log.e(TAG, "Unable to bind HeadsetService", e);
                }
            }
        }
        return false;
    }

    void doUnbind() {
    private void doUnbind() {
        synchronized (mConnection) {
            if (mService != null) {
                if (VDBG) Log.d(TAG, "Unbinding service...");
                try {
                    mAdapter.getBluetoothManager().unbindBluetoothProfileService(
                            BluetoothProfile.HEADSET, mConnection);
                } catch (RemoteException e) {
                    Log.e(TAG, "Unable to unbind HeadsetService", e);
                } finally {
                    mService = null;
                }
            }
        }
@@ -411,8 +409,8 @@ public final class BluetoothHeadset implements BluetoothProfile {
        if (mgr != null) {
            try {
                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
            } catch (Exception e) {
                Log.e(TAG, "", e);
            } catch (RemoteException re) {
                Log.e(TAG, "", re);
            }
        }
        mServiceListener = null;
@@ -1169,7 +1167,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
        @Override
        public void onServiceDisconnected(ComponentName className) {
            if (DBG) Log.d(TAG, "Proxy object disconnected");
            mService = null;
            doUnbind();
            mHandler.sendMessage(mHandler.obtainMessage(
                    MESSAGE_HEADSET_SERVICE_DISCONNECTED));
        }
+64 −131

File changed.

Preview size limit exceeded, changes collapsed.

Loading