OSDN Git Service

Fixed BT on/off issue
authorfredc <fredc@broadcom.com>
Thu, 19 Apr 2012 07:58:43 +0000 (00:58 -0700)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Tue, 17 Jul 2012 05:02:26 +0000 (22:02 -0700)
Change-Id: I47cbac9fc694d5604a664f20170eeed90eeee8e6

Conflicts:

jni/com_android_bluetooth_btservice_AdapterService.cpp

15 files changed:
jni/com_android_bluetooth_btservice_AdapterService.cpp
src/com/android/bluetooth/a2dp/A2dpService.java
src/com/android/bluetooth/a2dp/A2dpStateMachine.java
src/com/android/bluetooth/btservice/AdapterService.java
src/com/android/bluetooth/btservice/AdapterState.java
src/com/android/bluetooth/btservice/BondStateMachine.java
src/com/android/bluetooth/btservice/JniCallbacks.java
src/com/android/bluetooth/btservice/ProfileService.java [new file with mode: 0644]
src/com/android/bluetooth/hdp/HealthService.java
src/com/android/bluetooth/hfp/HeadsetService.java
src/com/android/bluetooth/hid/HidService.java
src/com/android/bluetooth/opp/BluetoothOppRfcommListener.java
src/com/android/bluetooth/opp/Constants.java
src/com/android/bluetooth/pan/PanService.java
src/com/android/bluetooth/pbap/BluetoothPbapService.java

index a9c276f..a18ab55 100755 (executable)
@@ -19,7 +19,6 @@
 namespace android {
 
 #define ADDITIONAL_NREFS 50
-
 static jmethodID method_stateChangeCallback;
 static jmethodID method_adapterPropertyChangedCallback;
 static jmethodID method_devicePropertyChangedCallback;
@@ -496,7 +495,7 @@ static bool cleanupNative(JNIEnv *env, jobject obj) {
     if (!sBluetoothInterface) return result;
 
     sBluetoothInterface->cleanup();
-    LOGV("%s: return from cleanup",__FUNCTION__);
+    LOGI("%s: return from cleanup",__FUNCTION__);
 
     env->DeleteGlobalRef(sJniCallbacksObj);
     return JNI_TRUE;
index e0bfe75..bd0d0bb 100755 (executable)
@@ -21,96 +21,44 @@ import java.util.Iterator;
 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;
     }
 
     /**
@@ -191,7 +139,4 @@ public class A2dpService extends Service {
         }
     };
 
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
 }
index fe49971..c7debf4 100755 (executable)
@@ -31,6 +31,7 @@ import android.os.ParcelUuid;
 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;
@@ -597,7 +598,7 @@ final class A2dpStateMachine extends 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) {
index d1923ac..4220fa7 100755 (executable)
@@ -79,8 +79,6 @@ public class AdapterService extends Service {
     private AdapterProperties mAdapterProperties;
     private int mAdapterState;
     private Context mContext;
-    private boolean mIsAirplaneSensitive;
-    private boolean mIsAirplaneToggleable;
     private static AdapterService sAdapterService;
 
     private AdapterState mAdapterStateMachine;
@@ -153,7 +151,7 @@ public class AdapterService extends Service {
         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()) {
@@ -169,7 +167,7 @@ public class AdapterService extends Service {
         } 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()) {
@@ -185,31 +183,6 @@ public class AdapterService extends Service {
         }
     }
 
-    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();
@@ -246,20 +219,6 @@ public class AdapterService extends Service {
     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) {
@@ -275,9 +234,11 @@ public class AdapterService extends Service {
             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;
@@ -300,11 +261,13 @@ public class AdapterService extends Service {
                 }
         };
 
-    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();
 
@@ -320,35 +283,153 @@ public class AdapterService extends Service {
                 }
             }
         }
-        
+
         //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
@@ -356,27 +437,44 @@ public class AdapterService extends Service {
             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();
@@ -388,8 +486,8 @@ public class AdapterService extends Service {
 
         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);
     }
@@ -410,49 +508,6 @@ public class AdapterService extends Service {
         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
      */
@@ -481,7 +536,7 @@ public class AdapterService extends Service {
         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);
@@ -759,20 +814,6 @@ public class AdapterService extends Service {
         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();
index 5042360..4e5fbe3 100755 (executable)
@@ -47,6 +47,9 @@ final class AdapterState extends StateMachine {
     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:");
@@ -76,6 +79,11 @@ final class AdapterState extends StateMachine {
 
         @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;
@@ -92,27 +100,7 @@ final class AdapterState extends StateMachine {
                        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);
@@ -132,13 +120,6 @@ final class AdapterState extends StateMachine {
         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
@@ -160,7 +141,7 @@ final class AdapterState extends StateMachine {
                    }
                    break;
                case USER_TURN_ON:
-               case AIRPLANE_MODE_OFF:
+               //case AIRPLANE_MODE_OFF:
                    //ignore
                    break;
                default:
@@ -188,23 +169,18 @@ final class AdapterState extends StateMachine {
                     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);
index a9f0f11..e854dcf 100755 (executable)
@@ -71,9 +71,11 @@ final class BondStateMachine extends StateMachine {
         @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) {
index 109db55..d829c19 100644 (file)
@@ -71,4 +71,5 @@ final class JniCallbacks {
     void adapterPropertyChangedCallback(int[] types, byte[][] val) {
         mAdapterProperties.adapterPropertyChangedCallback(types, val);
     }
+
 }
diff --git a/src/com/android/bluetooth/btservice/ProfileService.java b/src/com/android/bluetooth/btservice/ProfileService.java
new file mode 100644 (file)
index 0000000..9e86bb2
--- /dev/null
@@ -0,0 +1,110 @@
+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);
+    }
+}
index 8b80776..458deb2 100755 (executable)
@@ -34,21 +34,16 @@ import java.util.Map.Entry;
 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;
@@ -64,9 +59,8 @@ public class HealthService extends Service {
         classInitNative();
     }
 
-    @Override
-    public void onCreate() {
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
+    protected String getName() {
+        return TAG;
     }
 
     @Override
@@ -75,37 +69,7 @@ public class HealthService extends Service {
         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) {
@@ -120,12 +84,7 @@ public class HealthService extends Service {
             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,
@@ -138,14 +97,10 @@ public class HealthService extends Service {
         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
@@ -158,14 +113,20 @@ public class HealthService extends Service {
 
         //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 {
@@ -701,10 +662,6 @@ public class HealthService extends Service {
         return healthDevices;
     }
 
-    private void log(String msg) {
-        Log.d(TAG, msg);
-    }
-
     private class AppInfo {
         private IBluetoothHealthCallback mCallback;
         private int mAppId;
index bb0bd43..698c1af 100755 (executable)
@@ -25,28 +25,22 @@ import java.util.Iterator;
 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
@@ -55,76 +49,33 @@ public class HeadsetService extends Service {
         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() {
@@ -321,7 +272,4 @@ public class HeadsetService extends Service {
         }
     };
 
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
 }
index afc607c..1f76a2c 100755 (executable)
@@ -28,21 +28,16 @@ import java.util.Map;
 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;
@@ -62,9 +57,8 @@ public class HidService extends Service {
         classInitNative();
     }
 
-    @Override
-    public void onCreate() {
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
+    public String getName() {
+        return TAG;
     }
 
     @Override
@@ -73,66 +67,28 @@ public class HidService extends Service {
         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;
     }
 
     
@@ -509,9 +465,6 @@ public class HidService extends Service {
         }
     }
 
-    private void log(String msg) {
-        Log.d(TAG, msg);
-    }
 
     // Constants matching Hal header file bt_hh.h
     // bthh_connection_state_t
index b90d201..25ea89a 100755 (executable)
@@ -55,6 +55,7 @@ public class BluetoothOppRfcommListener {
     public static final int MSG_INCOMING_BTOPP_CONNECTION = 100;
 
     private volatile boolean mInterrupted;
+    private volatile boolean mFinish;
 
     private Thread mSocketAcceptThread;
 
@@ -146,16 +147,25 @@ public class BluetoothOppRfcommListener {
                         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);
                             }
@@ -177,7 +187,7 @@ public class BluetoothOppRfcommListener {
             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 {
index 8bb3312..cd57643 100644 (file)
@@ -226,12 +226,12 @@ public class Constants {
     /**
      * 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;
index 8523646..109e22d 100755 (executable)
@@ -37,25 +37,21 @@ import java.util.List;
 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;
@@ -71,37 +67,8 @@ public class PanService extends Service {
         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
@@ -110,14 +77,10 @@ public class PanService extends Service {
         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;
@@ -130,9 +93,7 @@ public class PanService extends Service {
             mPanIfName = null;
         if(mHandler != null)
             mHandler.removeCallbacksAndMessages(null);
-    }
-
-    private void start() {
+        
         if (DBG) log("start");
         mPanDevices = new HashMap<BluetoothDevice, BluetoothPanDevice>();
         mBluetoothIfaceAddresses = new ArrayList<String>();
@@ -144,28 +105,28 @@ public class PanService extends Service {
         }
 
         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() {
@@ -534,10 +495,6 @@ public class PanService extends Service {
         }
     }
 
-    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;
index 345b0c3..eacf1aa 100755 (executable)
@@ -60,6 +60,7 @@ import android.util.Log;
 
 
 import com.android.bluetooth.R;
+import com.android.bluetooth.btservice.AdapterService;
 
 import java.io.IOException;
 
@@ -171,7 +172,7 @@ public class BluetoothPbapService extends Service {
 
     private int mStartId = -1;
 
-    private IBluetooth mBluetoothService;
+    //private IBluetooth mBluetoothService;
 
     private boolean isWaitingAuthorization = false;
 
@@ -183,13 +184,13 @@ public class BluetoothPbapService extends Service {
     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
@@ -650,16 +651,16 @@ public class BluetoothPbapService extends Service {
             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");
-            }
+            }*/
         }
     }