/* *Copyright (c) 2013, The Linux Foundation. All rights reserved. * *Redistribution and use in source and binary forms, with or without *modification, are permitted provided that the following conditions are *met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT *ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS *BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN *IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package android.bluetooth; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import java.util.ArrayList; import java.util.List; /** * This class provides the APIs to control the Bluetooth Dun * Profile. * *
BluetoothDun is a proxy object for controlling the Bluetooth DUN * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get * the BluetoothDun proxy object. * *
Each method is protected with its appropriate permission. *@hide */ public final class BluetoothDun implements BluetoothProfile { private static final String TAG = "BluetoothDun"; private static final boolean DBG = false; private static final boolean VDBG = false; /** * Intent used to broadcast the change in connection state of the Dun * profile. * *
This intent will have 3 extras: *
{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTED}. * *
Requires {@link android.Manifest.permission#BLUETOOTH} permission to * receive. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CONNECTION_STATE_CHANGED = "codeaurora.bluetooth.dun.profile.action.CONNECTION_STATE_CHANGED"; private Context mContext; private ServiceListener mServiceListener; private BluetoothAdapter mAdapter; private IBluetoothDun mDunService; /** * Create a BluetoothDun proxy object for interacting with the local * Bluetooth Service which handles the Dun profile * */ /*package*/ BluetoothDun(Context context, ServiceListener l) { mContext = context; mServiceListener = l; mAdapter = BluetoothAdapter.getDefaultAdapter(); try { mAdapter.getBluetoothManager().registerStateChangeCallback(mStateChangeCallback); } catch (RemoteException re) { Log.w(TAG,"Unable to register BluetoothStateChangeCallback",re); } Log.d(TAG, "BluetoothDun() call bindService"); doBind(); } boolean doBind() { Intent intent = new Intent(IBluetoothDun.class.getName()); ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0); intent.setComponent(comp); if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0, android.os.Process.myUserHandle())) { Log.e(TAG, "Could not bind to Bluetooth Dun Service with " + intent); return false; } return true; } /*package*/ void close() { if (VDBG) log("close()"); mServiceListener = null; IBluetoothManager mgr = mAdapter.getBluetoothManager(); if (mgr != null) { try { mgr.unregisterStateChangeCallback(mStateChangeCallback); } catch (RemoteException re) { Log.w(TAG,"Unable to unregister BluetoothStateChangeCallback",re); } } synchronized (mConnection) { if ( mDunService != null) { try { mDunService = null; mContext.unbindService(mConnection); } catch (Exception re) { Log.e(TAG,"",re); } } } } protected void finalize() { close(); } private IBluetoothStateChangeCallback mStateChangeCallback = new IBluetoothStateChangeCallback.Stub() { @Override public void onBluetoothStateChange(boolean on) { //Handle enable request to bind again. Log.d(TAG, "onBluetoothStateChange on: " + on); if (on) { try { if (mDunService == null) { Log.d(TAG, "onBluetoothStateChange call bindService"); doBind(); } } catch (IllegalStateException e) { Log.e(TAG,"onBluetoothStateChange: could not bind to DUN service: ", e); } catch (SecurityException e) { Log.e(TAG,"onBluetoothStateChange: could not bind to DUN service: ", e); } } else { if (VDBG) Log.d(TAG,"Unbinding service..."); synchronized (mConnection) { if ( mDunService != null) { try { mDunService = null; mContext.unbindService(mConnection); } catch (Exception re) { Log.e(TAG,"",re); } } } } } }; /** * Initiate disconnection from DUN server. * *
Once the disconnection is initiated by any device either local host * or remote device, the state will transition from {@link #STATE_CONNECTED} * to {@link #STATE_DISCONNECTED}. * *
Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
* permission.
*
* @param device Remote Bluetooth Device
* @return false on immediate error,
* true otherwise
* @hide
*/
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
if (mDunService != null && isEnabled() &&
isValidDevice(device)) {
try {
return mDunService.disconnect(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
}
}
if (mDunService == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
/**
* {@inheritDoc}
*/
public List