namespace android {
#define ADDITIONAL_NREFS 50
-
static jmethodID method_stateChangeCallback;
static jmethodID method_adapterPropertyChangedCallback;
static jmethodID method_devicePropertyChangedCallback;
if (!sBluetoothInterface) return result;
sBluetoothInterface->cleanup();
- LOGV("%s: return from cleanup",__FUNCTION__);
+ LOGI("%s: return from cleanup",__FUNCTION__);
env->DeleteGlobalRef(sJniCallbacksObj);
return JNI_TRUE;
import java.util.Map;
import android.content.pm.PackageManager;
import com.android.bluetooth.btservice.AdapterService;
+import com.android.bluetooth.btservice.ProfileService;
/**
* Provides Bluetooth A2DP profile, as a service in the Bluetooth application.
* @hide
*/
-public class A2dpService extends Service {
- private static final String TAG = "BluetoothA2dpService";
+public class A2dpService extends ProfileService {
private static final boolean DBG = true;
+ private static final String TAG="A2dpService";
- static final String BLUETOOTH_ADMIN_PERM =
- android.Manifest.permission.BLUETOOTH_ADMIN;
- static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
-
- private BluetoothAdapter mAdapter;
private A2dpStateMachine mStateMachine;
- @Override
- public void onCreate() {
- log("onCreate");
- super.onCreate();
- mAdapter = BluetoothAdapter.getDefaultAdapter();
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- log("onBind");
- return mBinder;
- }
- public void onStart(Intent intent, int startId) {
- log("onStart");
-
- if (mAdapter == null) {
- Log.w(TAG, "Stopping profile service: device does not have BT");
- stop();
- }
-
- if (checkCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM)!=PackageManager.PERMISSION_GRANTED) {
- Log.e(TAG, "Permission denied!");
- return;
- }
-
- String action = intent.getStringExtra(AdapterService.EXTRA_ACTION);
- if (!AdapterService.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
- Log.e(TAG, "Invalid action " + action);
- return;
- }
-
- int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
- if(state==BluetoothAdapter.STATE_OFF) {
- stop();
- } else if (state== BluetoothAdapter.STATE_ON){
- start();
- }
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (DBG) log("Destroying service.");
- if(mAdapter != null)
- mAdapter = null;
- }
-
- private void start() {
+ protected boolean start() {
if (DBG) log("startService()");
mStateMachine = new A2dpStateMachine(this);
mStateMachine.start();
-
- //Notify adapter service
- AdapterService sAdapter = AdapterService.getAdapterService();
- if (sAdapter!= null) {
- sAdapter.onProfileServiceStateChanged(getClass().getName(), BluetoothAdapter.STATE_ON);
- }
+ return true;
}
- private void stop() {
+ protected boolean stop() {
if (DBG) log("stopService()");
if (mStateMachine!= null) {
mStateMachine.quit();
mStateMachine.cleanup();
mStateMachine=null;
}
+ return true;
+ }
- //Notify adapter service
- AdapterService sAdapter = AdapterService.getAdapterService();
- if (sAdapter!= null) {
- sAdapter.onProfileServiceStateChanged(getClass().getName(), BluetoothAdapter.STATE_OFF);
- }
- stopSelf();
+ protected String getName() {
+ return TAG;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ log("onBind");
+ return mBinder;
}
/**
}
};
- private static void log(String msg) {
- Log.d(TAG, msg);
- }
}
import android.util.Log;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
+import com.android.bluetooth.btservice.ProfileService;
import com.android.internal.util.IState;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- mContext.sendBroadcast(intent, A2dpService.BLUETOOTH_PERM);
+ mContext.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
if (DBG) log("Connection state " + device + ": " + prevState + "->" + newState);
AdapterService svc = AdapterService.getAdapterService();
if (svc != null) {
private AdapterProperties mAdapterProperties;
private int mAdapterState;
private Context mContext;
- private boolean mIsAirplaneSensitive;
- private boolean mIsAirplaneToggleable;
private static AdapterService sAdapterService;
private AdapterState mAdapterStateMachine;
if (mStopPending) {
//Process stop or disable pending
//Check if all services are stopped if so, do cleanup
- if (DBG) Log.d(TAG,"Checking if all profiles are stopped...");
+ //if (DBG) Log.d(TAG,"Checking if all profiles are stopped...");
synchronized (mProfileServicesState) {
Iterator<Map.Entry<String,Integer>> i = mProfileServicesState.entrySet().iterator();
while (i.hasNext()) {
} else if (mStartPending) {
//Process start pending
//Check if all services are started if so, update state
- if (DBG) Log.d(TAG,"Checking if all profiles are running...");
+ //if (DBG) Log.d(TAG,"Checking if all profiles are running...");
synchronized (mProfileServicesState) {
Iterator<Map.Entry<String,Integer>> i = mProfileServicesState.entrySet().iterator();
while (i.hasNext()) {
}
}
- private void processStarted() {
- Log.d(TAG, "processStarted()");
- IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
- registerForAirplaneMode(filter);
- registerReceiver(mReceiver, filter);
- mProfilesStarted = true;
- mStartPending = false;
- }
-
- private void processStopped() {
- Log.d(TAG, "processStopped");
- mStopPending=false;
- if (mBluetoothManager != null) {
- try {
- mBluetoothManager.unregisterAdapter(mManagerCallback);
- } catch (RemoteException re) {
- Log.e(TAG, "",re);
- }
- }
- mBondStateMachine.quit();
- mAdapterStateMachine.quit();
- finish();
- }
-
@Override
public void onCreate() {
super.onCreate();
public void onDestroy() {
if (DBG) Log.d(TAG, "onDestroy()");
super.onDestroy();
- if (mBondStateMachine != null) {
- mBondStateMachine.cleanup();
- mBondStateMachine = null;
- }
- if (mAdapterStateMachine != null) {
- mAdapterStateMachine.cleanup();
- mAdapterStateMachine = null;
- }
- if (mNativeAvailable) {
- Log.d(TAG, "Cleaning up adapter native....");
- cleanupNative();
- Log.d(TAG, "Done cleaning up adapter native....");
- mNativeAvailable=false;
- }
}
public int onStartCommand(Intent intent ,int flags, int startId) {
int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,BluetoothAdapter.ERROR);
if (DBG) Log.d(TAG,"onStartCommand(): state = " + Utils.debugGetAdapterStateString(state));
if (state == BluetoothAdapter.STATE_OFF) {
- stop();
+ Message m = mHandler.obtainMessage(MESSAGE_STOP);
+ mHandler.sendMessage(m);
} else if (state == BluetoothAdapter.STATE_ON) {
- start();
+ Message m = mHandler.obtainMessage(MESSAGE_START);
+ mHandler.sendMessage(m);
}
}
return START_STICKY;
}
};
- private void start() {
- if (DBG) Log.d(TAG,"start() called");
+ private void processStart() {
+ if (DBG) Log.d(TAG,"start() called, mStartPending= " + mStartPending + ", mProfilesStarted=" + mProfilesStarted);
if (mProfilesStarted || mStartPending) return;
if (DBG) Log.d(TAG,"starting bluetooth state machine and profiles..");
+
mStartPending=true;
+
mAdapterStateMachine.start();
mBondStateMachine.start();
}
}
}
-
+
//Start profile services
- for (int i=0; i <SUPPORTED_PROFILE_SERVICES.length;i++) {
- startProfileService(SUPPORTED_PROFILE_SERVICES[i]);
+ if (SUPPORTED_PROFILE_SERVICES.length==0 || mProfilesStarted) {
+ //Skip starting profiles and go to next step
+ processStarted();
+ } else {
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_START_TIMEOUT), MAX_TIMEOUT_MS);
+ for (int i=0; i <SUPPORTED_PROFILE_SERVICES.length;i++) {
+ startProfileService(SUPPORTED_PROFILE_SERVICES[i]);
+ }
}
}
+ private void processStartTimeout(){
+ //FIXME:
+ Log.e(TAG,"************Start Timed out!!!*******************");
+ mStartPending = false;
+ sendIntent(BluetoothAdapter.STATE_OFF);
+ //Stop
+ }
+
+ private void processStarted() {
+ Log.d(TAG, "processStarted()");
+ mHandler.removeMessages(MESSAGE_START_TIMEOUT);
+ mProfilesStarted = true;
+ //Enable bluetooth
+ Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON);
+ mAdapterStateMachine.sendMessage(m);
+ }
+
+ void onBluetoothEnableTimeout() {
+ Log.e(TAG, "Timeout occurred while enabling bluetooth...");
+ sendIntent(BluetoothAdapter.STATE_OFF);
+ //FIXME: stop services and cleanup
+ }
+
+ void onBluetoothEnabled() {
+ Log.d(TAG, "onBluetoothEnabled()");
+ Message m = mHandler.obtainMessage(MESSAGE_ENABLED);
+ mHandler.sendMessage(m);
+ }
+
+ void processEnabled() {
+ mStartPending = false;
+ mStopPending=false;
+ sendIntent(BluetoothAdapter.STATE_ON);
+ }
+
//Called as part of disable or independently (when just getting address)
- private void stop() {
- Log.d(TAG,"stop() called");
+ private void processStop() {
+ if (DBG) Log.d(TAG,"stop() called, mStopPending= " + mStopPending + ", mProfilesStarted=" + mProfilesStarted);
if (mStopPending) return;
mStopPending=true;
- if (mProfilesStarted) {
- //TODO: Start timeout
- mProfilesStarted = false;
- for (int i=SUPPORTED_PROFILE_SERVICES.length-1; i >=0;i--) {
+ if (SUPPORTED_PROFILE_SERVICES.length==0 || !mProfilesStarted) {
+ cleanup();
+ } else {
+ Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_OFF);
+ mAdapterStateMachine.sendMessage(m);
+ }
+ }
+
+ void onBluetoothDisabled() {
+ Log.d(TAG, "onBluetoothDisabled()");
+ Message m = mHandler.obtainMessage(MESSAGE_DISABLED);
+ mHandler.sendMessage(m);
+ }
+
+ void onBluetoothDisableTimeout() {
+ Log.e(TAG, "Timeout occurred while disable bluetooth...");
+ Message m = mHandler.obtainMessage(MESSAGE_DISABLED);
+ mHandler.sendMessage(m);
+ }
+
+ private void processDisabled() {
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_STOP_TIMEOUT), MAX_TIMEOUT_MS);
+ for (int i=SUPPORTED_PROFILE_SERVICES.length-1; i >=0;i--) {
stopProfileService(SUPPORTED_PROFILE_SERVICES[i]);
+ }
+ }
+
+ private void processStopTimeout() {
+ //FIXME:
+ Log.e(TAG,"************Stop Timed out!!!*******************");
+ processStopped();
+ }
+
+ private void processStopped() {
+ Log.d(TAG, "processStopped()");
+ mHandler.removeMessages(MESSAGE_STOP_TIMEOUT);
+
+ if (mBluetoothManager != null) {
+ try {
+ mBluetoothManager.unregisterAdapter(mManagerCallback);
+ } catch (RemoteException re) {
+ Log.e(TAG, "",re);
}
- } else {
- mStopPending=false;
- finish();
}
+ mBondStateMachine.quit();
+ mAdapterStateMachine.quit();
+ sendIntent(BluetoothAdapter.STATE_OFF);
+ cleanup();
+ }
+
+ void cleanup () {
+ if (DBG) Log.d(TAG, "cleanup()");
+
+ if (mBondStateMachine != null) {
+ mBondStateMachine.cleanup();
+ mBondStateMachine = null;
+ }
+ if (mAdapterStateMachine != null) {
+ mAdapterStateMachine.cleanup();
+ mAdapterStateMachine = null;
+ }
+ if (mNativeAvailable) {
+ Log.d(TAG, "Cleaning up adapter native....");
+ cleanupNative();
+ Log.d(TAG, "Done cleaning up adapter native....");
+ mNativeAvailable=false;
+ }
+ mStartPending = false;
+ mStopPending=false;
+ mProfilesStarted = false;
+ stopSelf();
+ }
+
+ private void sendIntent(int newState) {
+ int oldState = mAdapterProperties.getState();
+ Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
+ intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, oldState);
+ intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ mAdapterProperties.setState(newState);
+ mContext.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
+ //infoLog("Bluetooth State Change Intent: " + oldState + " -> " + newState);
}
private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED =1;
- private static final int MESSAGE_STARTED=2;
- private static final int MESSAGE_STOPPED=3;
- private static final int MESSAGE_PROFILE_CONNECTION_STATE_CHANGED=4;
+ private static final int MESSAGE_START=2;
+ private static final int MESSAGE_STOP=3;
+ private static final int MESSAGE_ENABLED=4;
+ private static final int MESSAGE_DISABLED=5;
+ private static final int MESSAGE_START_TIMEOUT=10;
+ private static final int MESSAGE_STOP_TIMEOUT=11;
+ private static final int MESSAGE_PROFILE_CONNECTION_STATE_CHANGED=20;
+ private static final int MAX_TIMEOUT_MS=3000;
private final Handler mHandler = new Handler() {
@Override
if (DBG) Log.d (TAG, "Message: " + msg.what);
switch (msg.what) {
+ case MESSAGE_START: {
+ processStart();
+ }
+ break;
+ case MESSAGE_START_TIMEOUT: {
+ processStartTimeout();
+ }
+ break;
+ case MESSAGE_ENABLED: {
+ processEnabled();
+ }
+ break;
+ case MESSAGE_STOP: {
+ processStop();
+ }
+ break;
+ case MESSAGE_STOP_TIMEOUT: {
+ processStopTimeout();
+ }
+ break;
+ case MESSAGE_DISABLED: {
+ processDisabled();
+ }
+ break;
case MESSAGE_PROFILE_SERVICE_STATE_CHANGED: {
Log.d(TAG, "MESSAGE_PROFILE_SERVICE_STATE_CHANGED");
processProfileServiceStateChanged((String) msg.obj, msg.arg1);
}
- break;
+ break;
case MESSAGE_PROFILE_CONNECTION_STATE_CHANGED: {
Log.d(TAG, "MESSAGE_PROFILE_CONNECTION_STATE_CHANGED");
processProfileStateChanged((BluetoothDevice) msg.obj, msg.arg1,msg.arg2, msg.getData().getInt("prevState",BluetoothAdapter.ERROR));
}
- break;
+ break;
}
}
};
- /**
- * Last step in the disable->stop->cleanup sequence
- */
- private void finish() {
- stopSelf();
- }
-
@SuppressWarnings("rawtypes")
private void startProfileService(Class service) {
String serviceName = service.getName();
mProfileServicesState.put(serviceName,BluetoothAdapter.STATE_TURNING_ON);
Intent i = new Intent(this,service);
- i.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED);
- i.putExtra(BluetoothAdapter.EXTRA_STATE,BluetoothAdapter.STATE_ON);
+ //i.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED);
+ //i.putExtra(BluetoothAdapter.EXTRA_STATE,BluetoothAdapter.STATE_ON);
if (DBG) Log.d(TAG, "Starting profile service "+serviceName);
startService(i);
}
startService(i);
}
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent == null) return;
-
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
- ContentResolver resolver = context.getContentResolver();
- // Query the airplane mode from Settings.System just to make sure that
- // some random app is not sending this intent and disabling bluetooth
- if (isAirplaneModeOn()) {
- mAdapterStateMachine.sendMessage(AdapterState.AIRPLANE_MODE_ON);
- } else {
- mAdapterStateMachine.sendMessage(AdapterState.AIRPLANE_MODE_OFF);
- }
- }
- }
- };
-
- private void registerForAirplaneMode(IntentFilter filter) {
- final ContentResolver resolver = mContext.getContentResolver();
- final String airplaneModeRadios = Settings.System.getString(resolver,
- Settings.System.AIRPLANE_MODE_RADIOS);
- final String toggleableRadios = Settings.System.getString(resolver,
- Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
-
- mIsAirplaneSensitive = airplaneModeRadios == null ? true :
- airplaneModeRadios.contains(Settings.System.RADIO_BLUETOOTH);
- mIsAirplaneToggleable = toggleableRadios == null ? false :
- toggleableRadios.contains(Settings.System.RADIO_BLUETOOTH);
-
- if (mIsAirplaneSensitive) {
- filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- }
- }
-
- /* Returns true if airplane mode is currently on */
- private final boolean isAirplaneModeOn() {
- return Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON, 0) == 1;
- }
- private boolean mPersistDisable;
-
/**
* Handlers for incoming service calls
*/
public boolean disable(boolean persist) {
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
- unregisterReceiver(mReceiver);
+ Log.d(TAG,"disable() called...");
int val = (persist ? 1 : 0);
Message m =
mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_OFF);
Log.e(TAG, msg);
}
- void persistBluetoothSetting(boolean setOn) {
- long origCallerIdentityToken = Binder.clearCallingIdentity();
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.BLUETOOTH_ON,
- setOn ? 1 : 0);
- Binder.restoreCallingIdentity(origCallerIdentityToken);
- }
-
- boolean getBluetoothPersistedSetting() {
- ContentResolver contentResolver = mContext.getContentResolver();
- return (Settings.Secure.getInt(contentResolver,
- Settings.Secure.BLUETOOTH_ON, 0) > 0);
- }
-
private native static void classInitNative();
private native boolean initNative();
private native void cleanupNative();
private OnState mOnState = new OnState();
private OffState mOffState = new OffState();
+ public boolean isCurrentlyOn() {
+ return mOnState == getCurrentState();
+ }
public AdapterState(AdapterService service, Context context,
AdapterProperties adapterProperties) {
super("BluetoothAdapterState:");
@Override
public boolean processMessage(Message msg) {
+ if (msg.what == SM_QUIT_CMD) {
+ Log.d(TAG, "Received quit request...");
+ return false;
+ }
+
switch(msg.what) {
case USER_TURN_ON:
int persist = msg.arg1;
transitionTo(mPendingCommandState);
}
break;
- case AIRPLANE_MODE_OFF:
- {
- if(mAdapterService.getBluetoothPersistedSetting()) {
- Log.i(TAG, "OffState : Turning BT on after Airplane"+
- " Mode OFF state");
- sendIntent(BluetoothAdapter.STATE_TURNING_ON);
- ret = mAdapterService.enableNative();
- if (!ret) {
- Log.e(TAG, "Error while turning Bluetooth On");
- sendIntent(BluetoothAdapter.STATE_OFF);
- } else {
- sendMessageDelayed(ENABLE_TIMEOUT,
- ENABLE_TIMEOUT_DELAY);
- transitionTo(mPendingCommandState);
- }
- }
- break;
- }
case USER_TURN_OFF:
- case AIRPLANE_MODE_ON:
- //ignore
break;
default:
Log.e(TAG, "Received unhandled state: " + msg.what);
public boolean processMessage(Message msg) {
switch(msg.what) {
case USER_TURN_OFF:
- int persist = msg.arg1;
- if (persist == 1) {
- //Persist disable immediately even before disable completes
- mAdapterService.persistBluetoothSetting(false);
- }
- //Fall Through
- case AIRPLANE_MODE_ON:
sendIntent(BluetoothAdapter.STATE_TURNING_OFF);
// Invoke onBluetoothDisable which shall trigger a
// setScanMode to SCAN_MODE_NONE
}
break;
case USER_TURN_ON:
- case AIRPLANE_MODE_OFF:
+ //case AIRPLANE_MODE_OFF:
//ignore
break;
default:
break;
case ENABLED_READY:
removeMessages(ENABLE_TIMEOUT);
- //Persist enable state only once enable completes
- if (mPendingPersistEnable) {
- mAdapterService.persistBluetoothSetting(true);
- mPendingPersistEnable=false;
- }
- mAdapterProperties.onBluetoothReady();
- sendIntent(BluetoothAdapter.STATE_ON);
transitionTo(mOnState);
+ mAdapterProperties.onBluetoothReady();
+ mAdapterService.onBluetoothEnabled();
break;
case DISABLED:
- sendIntent(BluetoothAdapter.STATE_OFF);
transitionTo(mOffState);
+ mAdapterService.onBluetoothDisabled();
break;
case ENABLE_TIMEOUT:
errorLog("Error enabling Bluetooth");
- sendIntent(BluetoothAdapter.STATE_OFF);
transitionTo(mOffState);
+ mAdapterService.onBluetoothEnableTimeout();
break;
default:
Log.e(TAG, "Received unhandled event:" + msg.what);
@Override
public boolean processMessage(Message msg) {
if (msg.what == SM_QUIT_CMD) {
+ Log.d(TAG, "Received quit request...");
return false;
}
+
BluetoothDevice dev = (BluetoothDevice)msg.obj;
switch(msg.what) {
void adapterPropertyChangedCallback(int[] types, byte[][] val) {
mAdapterProperties.adapterPropertyChangedCallback(types, val);
}
+
}
--- /dev/null
+package com.android.bluetooth.btservice;
+
+import android.app.Service;
+import android.bluetooth.BluetoothAdapter;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.IBinder;
+import android.util.Log;
+
+public abstract class ProfileService extends Service {
+ public static final String BLUETOOTH_ADMIN_PERM =
+ android.Manifest.permission.BLUETOOTH_ADMIN;
+ public static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
+
+ protected BluetoothAdapter mAdapter;
+ protected String mName;
+
+ protected String getName() {
+ return getClass().getSimpleName();
+ }
+
+ public abstract IBinder onBind(Intent intent);
+ protected abstract boolean start();
+ protected abstract boolean stop();
+
+ public boolean mStartError=false;
+ @Override
+ public void onCreate() {
+ mName = getName();
+ if (mName == null) {
+ mName = "UnknownProfileService";
+ }
+
+ log("onCreate");
+ super.onCreate();
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
+
+ //Start service
+ if (mAdapter == null) {
+ Log.e(mName, "Error starting profile. BluetoothAdapter is null");
+ } else {
+ mStartError = !start();
+ if (!mStartError) {
+ notifyProfileOn();
+ } else {
+ Log.e(mName, "Error starting profile. BluetoothAdapter is null");
+ }
+ }
+ }
+
+ public void onStart(Intent intent, int startId) {
+ log("onStart");
+
+ if (mStartError || mAdapter == null) {
+ Log.w(mName, "Stopping profile service: device does not have BT");
+ doStop();
+ return;
+ }
+
+ if (checkCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM)!=PackageManager.PERMISSION_GRANTED) {
+ Log.e(mName, "Permission denied!");
+ return;
+ }
+
+ String action = intent.getStringExtra(AdapterService.EXTRA_ACTION);
+ if (AdapterService.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
+ int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+ if(state==BluetoothAdapter.STATE_OFF) {
+ Log.d(mName, "Received stop request...Stopping profile...");
+ doStop();
+ }
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mAdapter = null;
+ log("Destroying service.");
+ }
+
+ private void doStop() {
+ if (stop()) {
+ notifyProfileOff();
+ stopSelf();
+ } else {
+ Log.e(mName, "Unable to stop profile");
+ }
+ }
+
+ protected void notifyProfileOn() {
+ //Notify adapter service
+ AdapterService sAdapter = AdapterService.getAdapterService();
+ if (sAdapter!= null) {
+ sAdapter.onProfileServiceStateChanged(getClass().getName(), BluetoothAdapter.STATE_ON);
+ }
+ }
+
+ protected void notifyProfileOff() {
+ //Notify adapter service
+ AdapterService sAdapter = AdapterService.getAdapterService();
+ if (sAdapter!= null) {
+ sAdapter.onProfileServiceStateChanged(getClass().getName(), BluetoothAdapter.STATE_OFF);
+ }
+ }
+
+ protected void log(String msg) {
+ Log.d(mName, msg);
+ }
+}
import com.android.bluetooth.Utils;
import android.content.pm.PackageManager;
import com.android.bluetooth.btservice.AdapterService;
+import com.android.bluetooth.btservice.ProfileService;
/**
* Provides Bluetooth Health Device profile, as a service in
* the Bluetooth application.
* @hide
*/
-public class HealthService extends Service {
- private static final String TAG = "BluetoothHealthService";
+public class HealthService extends ProfileService {
private static final boolean DBG = true;
-
- static final String BLUETOOTH_ADMIN_PERM =
- android.Manifest.permission.BLUETOOTH_ADMIN;
- static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
-
- private BluetoothAdapter mAdapter;
+ private static final String TAG="HealthService";
private List<HealthChannel> mHealthChannels;
private Map <BluetoothHealthAppConfiguration, AppInfo> mApps;
private Map <BluetoothDevice, Integer> mHealthDevices;
classInitNative();
}
- @Override
- public void onCreate() {
- mAdapter = BluetoothAdapter.getDefaultAdapter();
+ protected String getName() {
+ return TAG;
}
@Override
return mBinder;
}
- @Override
- public void onStart(Intent intent, int startId) {
- log("onStart");
- if (mAdapter == null) {
- Log.w(TAG, "Stopping Bluetooth HealthService: device does not have BT");
- stop();
- }
-
- if (checkCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM)!=PackageManager.PERMISSION_GRANTED) {
- Log.e(TAG, "Permission denied!");
- return;
- }
-
- String action = intent.getStringExtra(AdapterService.EXTRA_ACTION);
- if (!AdapterService.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
- Log.e(TAG, "Invalid action " + action);
- return;
- }
-
- int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
- if(state==BluetoothAdapter.STATE_OFF) {
- stop();
- } else if (state== BluetoothAdapter.STATE_ON){
- start();
- }
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (DBG) log("Destroying service.");
+ protected boolean start() {
//Cleanup other object references
if(mHealthChannels != null) {
mApps.clear();
mApps = null;
}
- if(mAdapter != null)
- mAdapter = null;
-
- }
-
- private void start() {
+
if (DBG) log("startService");
mHealthChannels = Collections.synchronizedList(new ArrayList<HealthChannel>());
mApps = Collections.synchronizedMap(new HashMap<BluetoothHealthAppConfiguration,
mHandler = new HealthServiceMessageHandler(looper);
initializeNative();
- //Notify adapter service
- AdapterService sAdapter = AdapterService.getAdapterService();
- if (sAdapter!= null) {
- sAdapter.onProfileServiceStateChanged(getClass().getName(), BluetoothAdapter.STATE_ON);
- }
+ return true;
}
- private void stop() {
+ protected boolean stop() {
if (DBG) log("stop()");
//Cleanup looper
//Cleanup native
cleanupNative();
-
- //Notify adapter service
- AdapterService sAdapter = AdapterService.getAdapterService();
- if (sAdapter!= null) {
- sAdapter.onProfileServiceStateChanged(getClass().getName(), BluetoothAdapter.STATE_OFF);
+
+ if(mHealthChannels != null) {
+ mHealthChannels.clear();
+ mHealthChannels = null;
+ }
+ if(mHealthDevices != null) {
+ mHealthDevices.clear();
+ mHealthDevices = null;
}
- if (DBG) log("stop() done.");
- stopSelf();
+ if(mApps != null) {
+ mApps.clear();
+ mApps = null;
+ }
+ return true;
}
private final class HealthServiceMessageHandler extends Handler {
return healthDevices;
}
- private void log(String msg) {
- Log.d(TAG, msg);
- }
-
private class AppInfo {
private IBluetoothHealthCallback mCallback;
private int mAppId;
import java.util.Map;
import android.content.pm.PackageManager;
import com.android.bluetooth.btservice.AdapterService;
+import com.android.bluetooth.btservice.ProfileService;
/**
* Provides Bluetooth Headset and Handsfree profile, as a service in
* the Bluetooth application.
* @hide
*/
-public class HeadsetService extends Service {
- private static final String TAG = "BluetoothHeadsetService";
+public class HeadsetService extends ProfileService {
private static final boolean DBG = true;
+ private static final String TAG = "HeadsetService";
- static final String BLUETOOTH_ADMIN_PERM =
- android.Manifest.permission.BLUETOOTH_ADMIN;
- static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
-
- private BluetoothAdapter mAdapter;
private HeadsetStateMachine mStateMachine;
+ private boolean mReceiverRegistered;
- @Override
- public void onCreate() {
- log("onCreate");
- super.onCreate();
- mAdapter = BluetoothAdapter.getDefaultAdapter();
+ protected String getName() {
+ return TAG;
}
@Override
return mBinder;
}
- public void onStart(Intent intent, int startId) {
- log("onStart");
-
- if (mAdapter == null) {
- Log.w(TAG, "Stopping profile service: device does not have BT");
- stop();
- }
-
- if (checkCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM)!=PackageManager.PERMISSION_GRANTED) {
- Log.e(TAG, "Permission denied!");
- return;
- }
-
- String action = intent.getStringExtra(AdapterService.EXTRA_ACTION);
- if (!AdapterService.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
- Log.e(TAG, "Invalid action " + action);
- return;
- }
-
- int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
- if(state==BluetoothAdapter.STATE_OFF) {
- stop();
- } else if (state== BluetoothAdapter.STATE_ON){
- start();
- }
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (DBG) log("Destroying service.");
- if(mAdapter != null)
- mAdapter = null;
- if(mStateMachine != null)
- {
- mStateMachine.quit();
- mStateMachine = null;
- }
- }
-
- private void start() {
+ protected boolean start() {
mStateMachine = new HeadsetStateMachine(this);
mStateMachine.start();
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(AudioManager.VOLUME_CHANGED_ACTION);
registerReceiver(mHeadsetReceiver, filter);
-
- //Notify adapter service
- AdapterService sAdapter = AdapterService.getAdapterService();
- if (sAdapter!= null) {
- sAdapter.onProfileServiceStateChanged(getClass().getName(), BluetoothAdapter.STATE_ON);
- }
+ mReceiverRegistered=true;
+ return true;
}
- private void stop() {
+ protected boolean stop() {
if (DBG) log("stopService()");
- unregisterReceiver(mHeadsetReceiver);
+ if (mReceiverRegistered) {
+ try {
+ unregisterReceiver(mHeadsetReceiver);
+ } catch (Exception e) {
+ Log.w(TAG,"Unable to unregister headset receiver",e);
+ }
+ mReceiverRegistered = false;
+ }
if (mStateMachine!= null) {
mStateMachine.quit();
mStateMachine.cleanup();
mStateMachine=null;
}
-
- //Notify adapter service
- AdapterService sAdapter = AdapterService.getAdapterService();
- if (sAdapter!= null) {
- sAdapter.onProfileServiceStateChanged(getClass().getName(), BluetoothAdapter.STATE_OFF);
- }
- stopSelf();
+ return true;
}
private final BroadcastReceiver mHeadsetReceiver = new BroadcastReceiver() {
}
};
- private static void log(String msg) {
- Log.d(TAG, msg);
- }
}
import com.android.bluetooth.Utils;
import android.content.pm.PackageManager;
import com.android.bluetooth.btservice.AdapterService;
+import com.android.bluetooth.btservice.ProfileService;
/**
* Provides Bluetooth Hid Host profile, as a service in
* the Bluetooth application.
* @hide
*/
-public class HidService extends Service {
- private static final String TAG = "BluetoothHidService";
+public class HidService extends ProfileService {
private static final boolean DBG = true;
-
- static final String BLUETOOTH_ADMIN_PERM =
- android.Manifest.permission.BLUETOOTH_ADMIN;
- static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
-
- private BluetoothAdapter mAdapter;
+ private static final String TAG = "HidService";
private Map<BluetoothDevice, Integer> mInputDevices;
private static final int MESSAGE_CONNECT = 1;
classInitNative();
}
- @Override
- public void onCreate() {
- mAdapter = BluetoothAdapter.getDefaultAdapter();
+ public String getName() {
+ return TAG;
}
@Override
return mBinder;
}
- public void onStart(Intent intent, int startId) {
- log("onStart");
-
- if (mAdapter == null) {
- Log.w(TAG, "Stopping profile service: device does not have BT");
- stop();
- }
-
- if (checkCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM)!=PackageManager.PERMISSION_GRANTED) {
- Log.e(TAG, "Permission denied!");
- return;
- }
-
- String action = intent.getStringExtra(AdapterService.EXTRA_ACTION);
- if (!AdapterService.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
- Log.e(TAG, "Invalid action " + action);
- return;
- }
-
- int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
- if(state==BluetoothAdapter.STATE_OFF) {
- stop();
- } else if (state== BluetoothAdapter.STATE_ON){
- start();
- }
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (DBG) log("Destroying service.");
- if(mAdapter != null)
- mAdapter = null;
+ protected boolean start() {
if(mInputDevices != null) {
mInputDevices.clear();
mInputDevices = null;
}
- }
-
- private void start() {
mInputDevices = Collections.synchronizedMap(new HashMap<BluetoothDevice, Integer>());
initializeNative();
- //Notify adapter service
- AdapterService sAdapter = AdapterService.getAdapterService();
- if (sAdapter!= null) {
- sAdapter.onProfileServiceStateChanged(getClass().getName(), BluetoothAdapter.STATE_ON);
- }
+ return true;
}
- private void stop() {
+ protected boolean stop() {
if (DBG) log("Stopping Bluetooth HidService");
cleanupNative();
- //Notify adapter service
- AdapterService sAdapter = AdapterService.getAdapterService();
- if (sAdapter!= null) {
- sAdapter.onProfileServiceStateChanged(getClass().getName(), BluetoothAdapter.STATE_OFF);
+ if(mInputDevices != null) {
+ mInputDevices.clear();
+ mInputDevices = null;
}
- stopSelf();
+
+ return true;
}
}
}
- private void log(String msg) {
- Log.d(TAG, msg);
- }
// Constants matching Hal header file bt_hh.h
// bthh_connection_state_t
public static final int MSG_INCOMING_BTOPP_CONNECTION = 100;
private volatile boolean mInterrupted;
+ private volatile boolean mFinish;
private Thread mSocketAcceptThread;
while (!mInterrupted) {
try {
if (V) Log.v(TAG, "Accepting connection...");
- clientSocket = mBtServerSocket.accept();
- if (V) Log.v(TAG, "Accepted connection from "
+ if (mBtServerSocket == null) {
+
+ }
+ BluetoothServerSocket sSocket = mBtServerSocket;
+ if (sSocket ==null) {
+ mInterrupted = true;
+
+ } else {
+ clientSocket = mBtServerSocket.accept();
+ if (V) Log.v(TAG, "Accepted connection from "
+ clientSocket.getRemoteDevice());
- BluetoothOppRfcommTransport transport = new BluetoothOppRfcommTransport(
+ BluetoothOppRfcommTransport transport = new BluetoothOppRfcommTransport(
clientSocket);
- Message msg = Message.obtain();
- msg.setTarget(mCallback);
- msg.what = MSG_INCOMING_BTOPP_CONNECTION;
- msg.obj = transport;
- msg.sendToTarget();
+ Message msg = Message.obtain();
+ msg.setTarget(mCallback);
+ msg.what = MSG_INCOMING_BTOPP_CONNECTION;
+ msg.obj = transport;
+ msg.sendToTarget();
+ }
} catch (IOException e) {
Log.e(TAG, "Error accept connection " + e);
}
Log.i(TAG, "stopping Accept Thread");
mInterrupted = true;
- if (Constants.USE_TCP_DEBUG) {
+ if (Constants.USE_TCP_DEBUG) {
if (V) Log.v(TAG, "close mTcpServerSocket");
if (mTcpServerSocket != null) {
try {
/**
* Debug level logging
*/
- public static final boolean DEBUG = false;
+ public static final boolean DEBUG = true;
/**
* Verbose level logging
*/
- public static final boolean VERBOSE = false;
+ public static final boolean VERBOSE = true;
/** use TCP socket instead of Rfcomm Socket to develop */
public static final boolean USE_TCP_DEBUG = false;
import java.util.Map;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
+import com.android.bluetooth.btservice.ProfileService;
/**
* Provides Bluetooth Pan Device profile, as a service in
* the Bluetooth application.
* @hide
*/
-public class PanService extends Service {
- private static final String TAG = "BluetoothPanService";
+public class PanService extends ProfileService {
+ private static final String TAG = "PanService";
private static final boolean DBG = true;
- static final String BLUETOOTH_ADMIN_PERM =
- android.Manifest.permission.BLUETOOTH_ADMIN;
- static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
-
private static final String BLUETOOTH_IFACE_ADDR_START= "192.168.44.1";
private static final int BLUETOOTH_MAX_PAN_CONNECTIONS = 5;
private static final int BLUETOOTH_PREFIX_LENGTH = 24;
- private BluetoothAdapter mAdapter;
private HashMap<BluetoothDevice, BluetoothPanDevice> mPanDevices;
private ArrayList<String> mBluetoothIfaceAddresses;
private int mMaxPanDevices;
classInitNative();
}
- @Override
- public void onCreate() {
- Log.d(TAG, "onCreate");
- mAdapter = BluetoothAdapter.getDefaultAdapter();
- }
-
- @Override
- public void onStart(Intent intent, int startId) {
- log("onStart");
- if (mAdapter == null) {
- Log.w(TAG, "Stopping Bluetooth Pan Service: device does not have BT");
- stop();
- }
-
- if (checkCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM)!=PackageManager.PERMISSION_GRANTED) {
- Log.e(TAG, "Permission denied!");
- return;
- }
-
- String action = intent.getStringExtra(AdapterService.EXTRA_ACTION);
- if (!AdapterService.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
- Log.e(TAG, "Invalid action " + action);
- return;
- }
-
- int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
- if(state==BluetoothAdapter.STATE_OFF) {
- stop();
- } else if (state== BluetoothAdapter.STATE_ON){
- start();
- }
+ protected String getName() {
+ return TAG;
}
@Override
return mBinder;
}
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (DBG) log("Stopping Bluetooth PanService");
+ protected boolean start() {
//Cleanup referenced objects here
- if(mAdapter != null)
- mAdapter = null;
+
if(mPanDevices != null) {
mPanDevices.clear();
mPanDevices = null;
mPanIfName = null;
if(mHandler != null)
mHandler.removeCallbacksAndMessages(null);
- }
-
- private void start() {
+
if (DBG) log("start");
mPanDevices = new HashMap<BluetoothDevice, BluetoothPanDevice>();
mBluetoothIfaceAddresses = new ArrayList<String>();
}
initializeNative();
-
- //Notify adapter service
- AdapterService sAdapter = AdapterService.getAdapterService();
- if (sAdapter!= null) {
- sAdapter.onProfileServiceStateChanged(getClass().getName(), BluetoothAdapter.STATE_ON);
- }
-
+ return true;
}
- private void stop() {
+ protected boolean stop() {
if (DBG) log("stop");
//Cleanup native
cleanupNative();
-
- //Notify adapter service
- AdapterService sAdapter = AdapterService.getAdapterService();
- if (sAdapter!= null) {
- sAdapter.onProfileServiceStateChanged(getClass().getName(), BluetoothAdapter.STATE_OFF);
+
+ if(mPanDevices != null) {
+ mPanDevices.clear();
+ mPanDevices = null;
+ }
+ if(mBluetoothIfaceAddresses != null) {
+ mBluetoothIfaceAddresses.clear();
+ mBluetoothIfaceAddresses = null;
}
- if (DBG) log("stop() done.");
- stopSelf();
+ if(mPanIfName != null)
+ mPanIfName = null;
+ if(mHandler != null)
+ mHandler.removeCallbacksAndMessages(null);
+ return true;
}
private final Handler mHandler = new Handler() {
}
}
- private void log(String msg) {
- Log.d(TAG, msg);
- }
-
// Constants matching Hal header file bt_hh.h
// bthh_connection_state_t
private final static int CONN_STATE_CONNECTED = 0;
import com.android.bluetooth.R;
+import com.android.bluetooth.btservice.AdapterService;
import java.io.IOException;
private int mStartId = -1;
- private IBluetooth mBluetoothService;
+ //private IBluetooth mBluetoothService;
private boolean isWaitingAuthorization = false;
public BluetoothPbapService() {
mState = BluetoothPbap.STATE_DISCONNECTED;
// IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
- IBinder b = null;
- if (b == null) {
- Log.e(TAG, "fail to get bluetooth service");
+ //IBinder b = null;
+ //if (b == null) {
+ // Log.e(TAG, "fail to get bluetooth service");
// throw new RuntimeException("Bluetooth service not available");
- return;
- }
- mBluetoothService = IBluetooth.Stub.asInterface(b);
+ // return;
+ //}
+ // mBluetoothService = IBluetooth.Stub.asInterface(b);
}
@Override
intent.putExtra(BluetoothPbap.PBAP_STATE, mState);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice);
sendBroadcast(intent, BLUETOOTH_PERM);
- if (mBluetoothService != null) {
- try {
- mBluetoothService.sendConnectionStateChange(mRemoteDevice, BluetoothProfile.PBAP,
- mState, prevState);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in sendConnectionStateChange");
- }
+ //if (mBluetoothService != null) {
+ AdapterService s = AdapterService.getAdapterService();
+ if (s != null) {
+ s.onProfileConnectionStateChanged(mRemoteDevice, BluetoothProfile.PBAP,
+ mState, prevState);
+ }
+ /*
} else {
Log.e(TAG, "null mBluetoothService");
- }
+ }*/
}
}