1ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/*
2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project
3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License");
5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License.
6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at
7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *      http://www.apache.org/licenses/LICENSE-2.0
9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software
11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS,
12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and
14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License.
15ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
16ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
17ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshpackage com.android.bluetooth.btservice;
18ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
19ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.bluetooth.BluetoothAdapter;
20ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Context;
21ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Intent;
22ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.os.Message;
233558402aae35c6b01c505be012d6736b0c758802Ajay Panickerimport android.os.UserManager;
24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.util.Log;
25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.State;
27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.StateMachine;
28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/**
30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * This state machine handles Bluetooth Adapter State.
31ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * States:
32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      {@link OnState} : Bluetooth is on at this state
33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      {@link OffState}: Bluetooth is off at this state. This is the initial
34ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      state.
35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      {@link PendingCommandState} : An enable / disable operation is pending.
36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * TODO(BT): Add per process on state.
37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
38ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
39ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshfinal class AdapterState extends StateMachine {
4034e323baafb5563c3874f95847ec544faf6923f8Matthew Xie    private static final boolean DBG = true;
41f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private static final boolean VDBG = true;
42ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private static final String TAG = "BluetoothAdapterState";
43ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
44f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BLE_TURN_ON = 0;
45ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    static final int USER_TURN_ON = 1;
46f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BREDR_STARTED=2;
4731ba132491053bc86d419a7d51fc04af3299c076fredc    static final int ENABLED_READY = 3;
48f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BLE_STARTED=4;
49ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
5031ba132491053bc86d419a7d51fc04af3299c076fredc    static final int USER_TURN_OFF = 20;
5131ba132491053bc86d419a7d51fc04af3299c076fredc    static final int BEGIN_DISABLE = 21;
5231ba132491053bc86d419a7d51fc04af3299c076fredc    static final int ALL_DEVICES_DISCONNECTED = 22;
53f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BLE_TURN_OFF = 23;
5474ae04c73312403e89db0f8e9bd9601d403b4783fredc
5531ba132491053bc86d419a7d51fc04af3299c076fredc    static final int DISABLED = 24;
56f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BLE_STOPPED=25;
57f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BREDR_STOPPED = 26;
58ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
59f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BREDR_START_TIMEOUT = 100;
6031ba132491053bc86d419a7d51fc04af3299c076fredc    static final int ENABLE_TIMEOUT = 101;
6131ba132491053bc86d419a7d51fc04af3299c076fredc    static final int DISABLE_TIMEOUT = 103;
62f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BLE_STOP_TIMEOUT = 104;
6357a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie    static final int SET_SCAN_MODE_TIMEOUT = 105;
64f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BLE_START_TIMEOUT = 106;
65f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BREDR_STOP_TIMEOUT = 107;
6631ba132491053bc86d419a7d51fc04af3299c076fredc
6731ba132491053bc86d419a7d51fc04af3299c076fredc    static final int USER_TURN_OFF_DELAY_MS=500;
6831ba132491053bc86d419a7d51fc04af3299c076fredc
6931ba132491053bc86d419a7d51fc04af3299c076fredc    //TODO: tune me
70f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private static final int ENABLE_TIMEOUT_DELAY = 12000;
7131ba132491053bc86d419a7d51fc04af3299c076fredc    private static final int DISABLE_TIMEOUT_DELAY = 8000;
72f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private static final int BREDR_START_TIMEOUT_DELAY = 4000;
73f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    //BLE_START_TIMEOUT can happen quickly as it just a start gattservice
74f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private static final int BLE_START_TIMEOUT_DELAY = 2000; //To start GattService
75f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private static final int BLE_STOP_TIMEOUT_DELAY = 2000;
76f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    //BREDR_STOP_TIMEOUT can < STOP_TIMEOUT
77f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private static final int BREDR_STOP_TIMEOUT_DELAY = 4000;
7831ba132491053bc86d419a7d51fc04af3299c076fredc    private static final int PROPERTY_OP_DELAY =2000;
796654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private AdapterService mAdapterService;
806654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private AdapterProperties mAdapterProperties;
81ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private PendingCommandState mPendingCommandState = new PendingCommandState();
82ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private OnState mOnState = new OnState();
83ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private OffState mOffState = new OffState();
84f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private BleOnState mBleOnState = new BleOnState();
85ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
8631ba132491053bc86d419a7d51fc04af3299c076fredc    public boolean isTurningOn() {
8731ba132491053bc86d419a7d51fc04af3299c076fredc        boolean isTurningOn=  mPendingCommandState.isTurningOn();
88f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        verboseLog("isTurningOn()=" + isTurningOn);
8931ba132491053bc86d419a7d51fc04af3299c076fredc        return isTurningOn;
90b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
9131ba132491053bc86d419a7d51fc04af3299c076fredc
92f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    public boolean isBleTurningOn() {
93f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        boolean isBleTurningOn=  mPendingCommandState.isBleTurningOn();
94f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        verboseLog("isBleTurningOn()=" + isBleTurningOn);
95f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        return isBleTurningOn;
96f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    }
97f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
98f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    public boolean isBleTurningOff() {
99f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        boolean isBleTurningOff =  mPendingCommandState.isBleTurningOff();
100f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        verboseLog("isBleTurningOff()=" + isBleTurningOff);
101f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        return isBleTurningOff;
102f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    }
103f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
10431ba132491053bc86d419a7d51fc04af3299c076fredc    public boolean isTurningOff() {
10531ba132491053bc86d419a7d51fc04af3299c076fredc        boolean isTurningOff= mPendingCommandState.isTurningOff();
106f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        verboseLog("isTurningOff()=" + isTurningOff);
10731ba132491053bc86d419a7d51fc04af3299c076fredc        return isTurningOff;
10831ba132491053bc86d419a7d51fc04af3299c076fredc    }
10931ba132491053bc86d419a7d51fc04af3299c076fredc
1106893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville    private AdapterState(AdapterService service, AdapterProperties adapterProperties) {
111ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        super("BluetoothAdapterState:");
112ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mOnState);
113f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        addState(mBleOnState);
114ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mOffState);
115ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mPendingCommandState);
116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterService = service;
117ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterProperties = adapterProperties;
1186654f5c903de510a70f9e72cd5ad7837b615d93ffredc        setInitialState(mOffState);
1196654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1206654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1216893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville    public static AdapterState make(AdapterService service, AdapterProperties adapterProperties) {
122f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        Log.d(TAG, "make() - Creating AdapterState");
1236893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        AdapterState as = new AdapterState(service, adapterProperties);
1246893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        as.start();
1256893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        return as;
1266893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville    }
12715d36984a79d6e35c659edb0efdf929f0b526bd5Fred
12815d36984a79d6e35c659edb0efdf929f0b526bd5Fred    public void doQuit() {
12915d36984a79d6e35c659edb0efdf929f0b526bd5Fred        quitNow();
13015d36984a79d6e35c659edb0efdf929f0b526bd5Fred    }
13115d36984a79d6e35c659edb0efdf929f0b526bd5Fred
1326654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public void cleanup() {
1333fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan        if(mAdapterProperties != null)
1343fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan            mAdapterProperties = null;
1353fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan        if(mAdapterService != null)
1363fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan            mAdapterService = null;
137ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
138ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
139ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class OffState extends State {
140ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
141ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
14231ba132491053bc86d419a7d51fc04af3299c076fredc            infoLog("Entering OffState");
143ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
144ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
145ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
146ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
1470eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            AdapterService adapterService = mAdapterService;
1480eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            if (adapterService == null) {
149f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                errorLog("Received message in OffState after cleanup: " + msg.what);
1500eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                return false;
1510eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            }
152f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
153f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            debugLog("Current state: OFF, message: " + msg.what);
154f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
155f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            switch(msg.what) {
156f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora               case BLE_TURN_ON:
157f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_TURNING_ON);
158f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   mPendingCommandState.setBleTurningOn(true);
159f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   transitionTo(mPendingCommandState);
160f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
161f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   adapterService.BleOnProcessStart();
162f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   break;
163f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
164f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora               case USER_TURN_OFF:
165f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   //TODO: Handle case of service started and stopped without enable
166f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   break;
167f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
168f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora               default:
169f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   return false;
170f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            }
171f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            return true;
172f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        }
173f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    }
174f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
175f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private class BleOnState extends State {
176f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        @Override
177f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        public void enter() {
178f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            infoLog("Entering BleOnState");
179f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        }
180f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
181f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        @Override
182f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        public boolean processMessage(Message msg) {
183f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
184f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            AdapterService adapterService = mAdapterService;
185f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            AdapterProperties adapterProperties = mAdapterProperties;
186f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            if ((adapterService == null) || (adapterProperties == null)) {
187f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                errorLog("Received message in BleOnState after cleanup: " + msg.what);
188f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                return false;
189f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            }
190f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
191f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            debugLog("Current state: BLE ON, message: " + msg.what);
192f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
193ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch(msg.what) {
194ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               case USER_TURN_ON:
1954852c5686229f1014e9851f4e9a3a19547581b45fredc                   notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_ON);
19631ba132491053bc86d419a7d51fc04af3299c076fredc                   mPendingCommandState.setTurningOn(true);
19731ba132491053bc86d419a7d51fc04af3299c076fredc                   transitionTo(mPendingCommandState);
198f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   sendMessageDelayed(BREDR_START_TIMEOUT, BREDR_START_TIMEOUT_DELAY);
199f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   adapterService.startCoreServices();
200ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   break;
201f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
202ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               case USER_TURN_OFF:
203f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_TURNING_OFF);
204f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   mPendingCommandState.setBleTurningOff(true);
205f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   adapterProperties.onBleDisable();
206f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   transitionTo(mPendingCommandState);
207f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   sendMessageDelayed(DISABLE_TIMEOUT, DISABLE_TIMEOUT_DELAY);
208f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   boolean ret = adapterService.disableNative();
209f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   if (!ret) {
210f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        removeMessages(DISABLE_TIMEOUT);
211f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        errorLog("Error while calling disableNative");
212f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        //FIXME: what about post enable services
213f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        mPendingCommandState.setBleTurningOff(false);
214f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_ON);
215f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   }
216ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   break;
217f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
218ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               default:
219ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   return false;
220ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
221ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
222ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
223ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
224ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
225ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class OnState extends State {
226ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
227ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
228f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            infoLog("Entering OnState");
229f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
2300eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            AdapterService adapterService = mAdapterService;
2310eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            if (adapterService == null) {
232f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                errorLog("Entered OnState after cleanup");
2330eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                return;
2340eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            }
2356fb4b2407f2ae6d87b1f026870f66d717a915973venkata Jagadeesh            adapterService.updateUuids();
2360eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            adapterService.autoConnect();
237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
238ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
239ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
240ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
2410eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            AdapterProperties adapterProperties = mAdapterProperties;
2420eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            if (adapterProperties == null) {
243f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                errorLog("Received message in OnState after cleanup: " + msg.what);
2440eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                return false;
2450eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            }
24615d36984a79d6e35c659edb0efdf929f0b526bd5Fred
247f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            debugLog("Current state: ON, message: " + msg.what);
248f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch(msg.what) {
250f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora               case BLE_TURN_OFF:
2514852c5686229f1014e9851f4e9a3a19547581b45fredc                   notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_OFF);
25231ba132491053bc86d419a7d51fc04af3299c076fredc                   mPendingCommandState.setTurningOff(true);
25331ba132491053bc86d419a7d51fc04af3299c076fredc                   transitionTo(mPendingCommandState);
25431ba132491053bc86d419a7d51fc04af3299c076fredc
255d570893c5ec3bc9fd1860aa0355c550d3a51f8ddKausik Sinnaswamy                   // Invoke onBluetoothDisable which shall trigger a
256d570893c5ec3bc9fd1860aa0355c550d3a51f8ddKausik Sinnaswamy                   // setScanMode to SCAN_MODE_NONE
25757a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie                   Message m = obtainMessage(SET_SCAN_MODE_TIMEOUT);
25831ba132491053bc86d419a7d51fc04af3299c076fredc                   sendMessageDelayed(m, PROPERTY_OP_DELAY);
2590eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                   adapterProperties.onBluetoothDisable();
260ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   break;
26131ba132491053bc86d419a7d51fc04af3299c076fredc
262ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               case USER_TURN_ON:
263ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   break;
264f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
265ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               default:
266ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   return false;
267ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
268ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
269ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
271ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
272ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class PendingCommandState extends State {
27331ba132491053bc86d419a7d51fc04af3299c076fredc        private boolean mIsTurningOn;
27431ba132491053bc86d419a7d51fc04af3299c076fredc        private boolean mIsTurningOff;
275f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        private boolean mIsBleTurningOn;
276f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        private boolean mIsBleTurningOff;
27731ba132491053bc86d419a7d51fc04af3299c076fredc
278ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
279f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            infoLog("Entering PendingCommandState");
28031ba132491053bc86d419a7d51fc04af3299c076fredc        }
28131ba132491053bc86d419a7d51fc04af3299c076fredc
28231ba132491053bc86d419a7d51fc04af3299c076fredc        public void setTurningOn(boolean isTurningOn) {
28331ba132491053bc86d419a7d51fc04af3299c076fredc            mIsTurningOn = isTurningOn;
28431ba132491053bc86d419a7d51fc04af3299c076fredc        }
28531ba132491053bc86d419a7d51fc04af3299c076fredc
28631ba132491053bc86d419a7d51fc04af3299c076fredc        public boolean isTurningOn() {
28731ba132491053bc86d419a7d51fc04af3299c076fredc            return mIsTurningOn;
28831ba132491053bc86d419a7d51fc04af3299c076fredc        }
28931ba132491053bc86d419a7d51fc04af3299c076fredc
29031ba132491053bc86d419a7d51fc04af3299c076fredc        public void setTurningOff(boolean isTurningOff) {
29131ba132491053bc86d419a7d51fc04af3299c076fredc            mIsTurningOff = isTurningOff;
29231ba132491053bc86d419a7d51fc04af3299c076fredc        }
29331ba132491053bc86d419a7d51fc04af3299c076fredc
29431ba132491053bc86d419a7d51fc04af3299c076fredc        public boolean isTurningOff() {
29531ba132491053bc86d419a7d51fc04af3299c076fredc            return mIsTurningOff;
29631ba132491053bc86d419a7d51fc04af3299c076fredc        }
29731ba132491053bc86d419a7d51fc04af3299c076fredc
298f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        public void setBleTurningOn(boolean isBleTurningOn) {
299f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            mIsBleTurningOn = isBleTurningOn;
300f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        }
301f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
302f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        public boolean isBleTurningOn() {
303f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            return mIsBleTurningOn;
304f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        }
305f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
306f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        public void setBleTurningOff(boolean isBleTurningOff) {
307f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            mIsBleTurningOff = isBleTurningOff;
308f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        }
309f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
310f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        public boolean isBleTurningOff() {
311f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            return mIsBleTurningOff;
312f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        }
313f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
314ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
315ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
31615d36984a79d6e35c659edb0efdf929f0b526bd5Fred
31731ba132491053bc86d419a7d51fc04af3299c076fredc            boolean isTurningOn= isTurningOn();
31831ba132491053bc86d419a7d51fc04af3299c076fredc            boolean isTurningOff = isTurningOff();
319f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            boolean isBleTurningOn = isBleTurningOn();
320f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            boolean isBleTurningOff = isBleTurningOff();
32115d36984a79d6e35c659edb0efdf929f0b526bd5Fred
3220eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            AdapterService adapterService = mAdapterService;
3230eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            AdapterProperties adapterProperties = mAdapterProperties;
3240eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            if ((adapterService == null) || (adapterProperties == null)) {
325f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                errorLog("Received message in PendingCommandState after cleanup: " + msg.what);
3260eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                return false;
3270eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            }
3280eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu
329f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            debugLog("Current state: PENDING_COMMAND, message: " + msg.what);
330f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
331ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch (msg.what) {
332ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case USER_TURN_ON:
333f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    if (isBleTurningOff || isTurningOff) { //TODO:do we need to send it after ble turn off also??
334f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        infoLog("Deferring USER_TURN_ON request...");
33531ba132491053bc86d419a7d51fc04af3299c076fredc                        deferMessage(msg);
33631ba132491053bc86d419a7d51fc04af3299c076fredc                    }
33731ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
338f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
339ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case USER_TURN_OFF:
340f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    if (isTurningOn || isBleTurningOn) {
341f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        infoLog("Deferring USER_TURN_OFF request...");
342f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        deferMessage(msg);
343f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    }
344f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    break;
345f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
346f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BLE_TURN_ON:
347f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    if (isTurningOff || isBleTurningOff) {
348f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        infoLog("Deferring BLE_TURN_ON request...");
349f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        deferMessage(msg);
350f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    }
351f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    break;
352f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
353f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BLE_TURN_OFF:
354f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    if (isTurningOn || isBleTurningOn) {
355f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        infoLog("Deferring BLE_TURN_OFF request...");
35631ba132491053bc86d419a7d51fc04af3299c076fredc                        deferMessage(msg);
35731ba132491053bc86d419a7d51fc04af3299c076fredc                    }
358ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
359f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
360f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BLE_STARTED:
36131ba132491053bc86d419a7d51fc04af3299c076fredc                    //Remove start timeout
362f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    removeMessages(BLE_START_TIMEOUT);
36331ba132491053bc86d419a7d51fc04af3299c076fredc
36431ba132491053bc86d419a7d51fc04af3299c076fredc                    //Enable
3653558402aae35c6b01c505be012d6736b0c758802Ajay Panicker                    boolean isGuest = UserManager.get(mAdapterService).isGuestUser();
3663558402aae35c6b01c505be012d6736b0c758802Ajay Panicker                    if (!adapterService.enableNative(isGuest)) {
367f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        errorLog("Error while turning Bluetooth on");
3684852c5686229f1014e9851f4e9a3a19547581b45fredc                        notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
36931ba132491053bc86d419a7d51fc04af3299c076fredc                        transitionTo(mOffState);
37031ba132491053bc86d419a7d51fc04af3299c076fredc                    } else {
37131ba132491053bc86d419a7d51fc04af3299c076fredc                        sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY);
37231ba132491053bc86d419a7d51fc04af3299c076fredc                    }
37331ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
37431ba132491053bc86d419a7d51fc04af3299c076fredc
375f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BREDR_STARTED:
376f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    //Remove start timeout
377f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    removeMessages(BREDR_START_TIMEOUT);
3780eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                    adapterProperties.onBluetoothReady();
37931ba132491053bc86d419a7d51fc04af3299c076fredc                    mPendingCommandState.setTurningOn(false);
38031ba132491053bc86d419a7d51fc04af3299c076fredc                    transitionTo(mOnState);
3814852c5686229f1014e9851f4e9a3a19547581b45fredc                    notifyAdapterStateChange(BluetoothAdapter.STATE_ON);
38231ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
38331ba132491053bc86d419a7d51fc04af3299c076fredc
384f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case ENABLED_READY:
385f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    removeMessages(ENABLE_TIMEOUT);
386f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    mPendingCommandState.setBleTurningOn(false);
387f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    transitionTo(mBleOnState);
388f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_ON);
389f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    break;
390f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
39157a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie                case SET_SCAN_MODE_TIMEOUT:
392f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                     warningLog("Timeout while setting scan mode. Continuing with disable...");
39357a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie                     //Fall through
394f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BEGIN_DISABLE:
39557a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie                    removeMessages(SET_SCAN_MODE_TIMEOUT);
396f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    sendMessageDelayed(BREDR_STOP_TIMEOUT, BREDR_STOP_TIMEOUT_DELAY);
397f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    adapterService.stopProfileServices();
398ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
399f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
400ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case DISABLED:
401ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                    if (isTurningOn) {
402ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                        removeMessages(ENABLE_TIMEOUT);
403f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        errorLog("Error enabling Bluetooth - hardware init failed?");
404ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                        mPendingCommandState.setTurningOn(false);
405ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                        transitionTo(mOffState);
4060eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                        adapterService.stopProfileServices();
407ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                        notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
408ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                        break;
409ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                    }
41031ba132491053bc86d419a7d51fc04af3299c076fredc                    removeMessages(DISABLE_TIMEOUT);
411f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    sendMessageDelayed(BLE_STOP_TIMEOUT, BLE_STOP_TIMEOUT_DELAY);
412f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    if (adapterService.stopGattProfileService()) {
413f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        debugLog("Stopping Gatt profile services that were post enabled");
41431ba132491053bc86d419a7d51fc04af3299c076fredc                        break;
41531ba132491053bc86d419a7d51fc04af3299c076fredc                    }
41674ae04c73312403e89db0f8e9bd9601d403b4783fredc                    //Fall through if no services or services already stopped
417f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BLE_STOPPED:
418f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    removeMessages(BLE_STOP_TIMEOUT);
419f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    setBleTurningOff(false);
42031ba132491053bc86d419a7d51fc04af3299c076fredc                    transitionTo(mOffState);
4214852c5686229f1014e9851f4e9a3a19547581b45fredc                    notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
42231ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
423f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
424f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BREDR_STOPPED:
425f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    removeMessages(BREDR_STOP_TIMEOUT);
426f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    setTurningOff(false);
427f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    transitionTo(mBleOnState);
428f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_ON);
429f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    break;
430f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
431f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BLE_START_TIMEOUT:
432f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    errorLog("Error enabling Bluetooth (BLE start timeout)");
433f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    mPendingCommandState.setBleTurningOn(false);
434ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    transitionTo(mOffState);
4354852c5686229f1014e9851f4e9a3a19547581b45fredc                    notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
436ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
437f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
438f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BREDR_START_TIMEOUT:
439f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    errorLog("Error enabling Bluetooth (start timeout)");
44031ba132491053bc86d419a7d51fc04af3299c076fredc                    mPendingCommandState.setTurningOn(false);
441f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    transitionTo(mBleOnState);
442f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_ON);
443f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    break;
444f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
445f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case ENABLE_TIMEOUT:
446f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    errorLog("Error enabling Bluetooth (enable timeout)");
447f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    mPendingCommandState.setBleTurningOn(false);
448ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    transitionTo(mOffState);
4494852c5686229f1014e9851f4e9a3a19547581b45fredc                    notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
45031ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
451f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
452f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BREDR_STOP_TIMEOUT:
453f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    errorLog("Error stopping Bluetooth profiles (stop timeout)");
454f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    mPendingCommandState.setTurningOff(false);
455f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    transitionTo(mBleOnState);
456f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_ON);
457f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    break;
458f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
459f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BLE_STOP_TIMEOUT:
460f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    errorLog("Error stopping Bluetooth profiles (BLE stop timeout)");
46131ba132491053bc86d419a7d51fc04af3299c076fredc                    mPendingCommandState.setTurningOff(false);
46231ba132491053bc86d419a7d51fc04af3299c076fredc                    transitionTo(mOffState);
463f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
46431ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
465f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
46631ba132491053bc86d419a7d51fc04af3299c076fredc                case DISABLE_TIMEOUT:
467f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    errorLog("Error disabling Bluetooth (disable timeout)");
46868cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                    if (isTurningOn)
46968cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                        mPendingCommandState.setTurningOn(false);
47068cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                    adapterService.stopProfileServices();
47168cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                    adapterService.stopGattProfileService();
47231ba132491053bc86d419a7d51fc04af3299c076fredc                    mPendingCommandState.setTurningOff(false);
47368cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                    setBleTurningOff(false);
47468cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                    transitionTo(mOffState);
47568cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                    notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
476ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
477f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
478ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                default:
479ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    return false;
480ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
481ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
482ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
483ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
484ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
4854852c5686229f1014e9851f4e9a3a19547581b45fredc    private void notifyAdapterStateChange(int newState) {
4860eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        AdapterService adapterService = mAdapterService;
4870eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        AdapterProperties adapterProperties = mAdapterProperties;
4880eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        if ((adapterService == null) || (adapterProperties == null)) {
489f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            errorLog("notifyAdapterStateChange after cleanup:" + newState);
4900eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            return;
4910eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        }
4920eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu
4930eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        int oldState = adapterProperties.getState();
4940eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        adapterProperties.setState(newState);
4954852c5686229f1014e9851f4e9a3a19547581b45fredc        infoLog("Bluetooth adapter state changed: " + oldState + "-> " + newState);
4960eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        adapterService.updateAdapterState(oldState, newState);
497ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
498ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
499ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    void stateChangeCallback(int status) {
500ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (status == AbstractionLayer.BT_STATE_OFF) {
501ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            sendMessage(DISABLED);
502f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
503ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        } else if (status == AbstractionLayer.BT_STATE_ON) {
504ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh            // We should have got the property change for adapter and remote devices.
505ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh            sendMessage(ENABLED_READY);
506f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
507ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        } else {
508ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            errorLog("Incorrect status in stateChangeCallback");
509ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
510ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
511ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
512ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void infoLog(String msg) {
513ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (DBG) Log.i(TAG, msg);
514ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
515ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
516f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private void debugLog(String msg) {
517f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        if (DBG) Log.d(TAG, msg);
518f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    }
519f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
520f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private void warningLog(String msg) {
521f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        if (DBG) Log.d(TAG, msg);
522f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    }
523f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
524f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private void verboseLog(String msg) {
525f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        if (VDBG) Log.v(TAG, msg);
526f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    }
527f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
528ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void errorLog(String msg) {
529ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Log.e(TAG, msg);
530ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
53115d36984a79d6e35c659edb0efdf929f0b526bd5Fred
532ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
533