ProfileService.java revision 31ba132491053bc86d419a7d51fc04af3299c076
1b5cc776c9353a203cdde97e62b25f05d9633d14cfredcpackage com.android.bluetooth.btservice;
2b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
3b5cc776c9353a203cdde97e62b25f05d9633d14cfredcimport android.app.Service;
4b5cc776c9353a203cdde97e62b25f05d9633d14cfredcimport android.bluetooth.BluetoothAdapter;
5b5cc776c9353a203cdde97e62b25f05d9633d14cfredcimport android.content.Intent;
6b5cc776c9353a203cdde97e62b25f05d9633d14cfredcimport android.content.pm.PackageManager;
7b5cc776c9353a203cdde97e62b25f05d9633d14cfredcimport android.os.IBinder;
8b5cc776c9353a203cdde97e62b25f05d9633d14cfredcimport android.util.Log;
9b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
10b5cc776c9353a203cdde97e62b25f05d9633d14cfredcpublic abstract class ProfileService extends Service {
11b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    public static final String BLUETOOTH_ADMIN_PERM =
12b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            android.Manifest.permission.BLUETOOTH_ADMIN;
13b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    public static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
14b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
1531ba132491053bc86d419a7d51fc04af3299c076fredc    //Profile services will not be automatically restarted.
1631ba132491053bc86d419a7d51fc04af3299c076fredc    //They must be explicitly restarted by AdapterService
1731ba132491053bc86d419a7d51fc04af3299c076fredc    private static final int PROFILE_SERVICE_MODE=Service.START_NOT_STICKY;
1831ba132491053bc86d419a7d51fc04af3299c076fredc
19b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    protected BluetoothAdapter mAdapter;
20b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    protected String mName;
21b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
22b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    protected String getName() {
23b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        return getClass().getSimpleName();
24b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
25b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
26b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    public abstract IBinder onBind(Intent intent);
27b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    protected abstract boolean start();
28b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    protected abstract boolean stop();
29b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
30b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    public boolean mStartError=false;
31b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    @Override
32b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    public void onCreate() {
33b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        mName = getName();
34b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        if (mName == null) {
35b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            mName = "UnknownProfileService";
36b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        }
3731ba132491053bc86d419a7d51fc04af3299c076fredc        mAdapter = BluetoothAdapter.getDefaultAdapter();
38b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
39b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        log("onCreate");
40b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        super.onCreate();
4131ba132491053bc86d419a7d51fc04af3299c076fredc    }
4231ba132491053bc86d419a7d51fc04af3299c076fredc
4331ba132491053bc86d419a7d51fc04af3299c076fredc    private void doStart(Intent intent) {
44b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
45b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        //Start service
46b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        if (mAdapter == null) {
47b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            Log.e(mName, "Error starting profile. BluetoothAdapter is null");
48b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        } else {
49b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            mStartError = !start();
50b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            if (!mStartError) {
5131ba132491053bc86d419a7d51fc04af3299c076fredc                notifyProfileServiceStateChange(BluetoothAdapter.STATE_ON);
52b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            } else {
53b5cc776c9353a203cdde97e62b25f05d9633d14cfredc                Log.e(mName, "Error starting profile. BluetoothAdapter is null");
54b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            }
55b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        }
56b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
57b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
5831ba132491053bc86d419a7d51fc04af3299c076fredc    public int onStartCommand(Intent intent, int flags, int startId) {
5931ba132491053bc86d419a7d51fc04af3299c076fredc        log("onStartCommand()");
60b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        if (mStartError || mAdapter == null) {
61b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            Log.w(mName, "Stopping profile service: device does not have BT");
6231ba132491053bc86d419a7d51fc04af3299c076fredc            doStop(intent);
6331ba132491053bc86d419a7d51fc04af3299c076fredc            return PROFILE_SERVICE_MODE;
64b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        }
65b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
66b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        if (checkCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM)!=PackageManager.PERMISSION_GRANTED) {
67b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            Log.e(mName, "Permission denied!");
6831ba132491053bc86d419a7d51fc04af3299c076fredc            return PROFILE_SERVICE_MODE;
69b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        }
70b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
7131ba132491053bc86d419a7d51fc04af3299c076fredc        if (intent == null) {
7231ba132491053bc86d419a7d51fc04af3299c076fredc            Log.d(mName, "Restarting profile service...");
7331ba132491053bc86d419a7d51fc04af3299c076fredc            return PROFILE_SERVICE_MODE;
7431ba132491053bc86d419a7d51fc04af3299c076fredc        } else {
7531ba132491053bc86d419a7d51fc04af3299c076fredc            String action = intent.getStringExtra(AdapterService.EXTRA_ACTION);
7631ba132491053bc86d419a7d51fc04af3299c076fredc            if (AdapterService.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
7731ba132491053bc86d419a7d51fc04af3299c076fredc                int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
7831ba132491053bc86d419a7d51fc04af3299c076fredc                if(state==BluetoothAdapter.STATE_OFF) {
7931ba132491053bc86d419a7d51fc04af3299c076fredc                    Log.d(mName, "Received stop request...Stopping profile...");
8031ba132491053bc86d419a7d51fc04af3299c076fredc                    doStop(intent);
8131ba132491053bc86d419a7d51fc04af3299c076fredc                } else if (state == BluetoothAdapter.STATE_ON) {
8231ba132491053bc86d419a7d51fc04af3299c076fredc                    Log.d(mName, "Received start request. Starting profile...");
8331ba132491053bc86d419a7d51fc04af3299c076fredc                    doStart(intent);
8431ba132491053bc86d419a7d51fc04af3299c076fredc                }
85b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            }
86b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        }
8731ba132491053bc86d419a7d51fc04af3299c076fredc        return PROFILE_SERVICE_MODE;
88b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
89b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
90b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    @Override
91b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    public void onDestroy() {
92b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        super.onDestroy();
93b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        log("Destroying service.");
94b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
95b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
9631ba132491053bc86d419a7d51fc04af3299c076fredc    private void doStop(Intent intent) {
97b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        if (stop()) {
9831ba132491053bc86d419a7d51fc04af3299c076fredc            notifyProfileServiceStateChange(BluetoothAdapter.STATE_OFF);
99b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            stopSelf();
100b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        } else {
101b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            Log.e(mName, "Unable to stop profile");
102b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        }
103b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
104b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
10531ba132491053bc86d419a7d51fc04af3299c076fredc    protected void notifyProfileServiceStateChange(int state) {
106b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        //Notify adapter service
107b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        AdapterService sAdapter = AdapterService.getAdapterService();
108b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        if (sAdapter!= null) {
10931ba132491053bc86d419a7d51fc04af3299c076fredc            sAdapter.onProfileServiceStateChanged(getClass().getName(), state);
110b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        }
111b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
112b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
113b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
114b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    protected void log(String msg) {
115b5cc776c9353a203cdde97e62b25f05d9633d14cfredc        Log.d(mName, msg);
116b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
117b5cc776c9353a203cdde97e62b25f05d9633d14cfredc}
118