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.os.Message;
21c63ef51ba5f9d355239959bcfe8803987adb1f38Ajay Panickerimport android.os.UserManager;
22ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.util.Log;
23ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.State;
25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.StateMachine;
26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/**
28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * This state machine handles Bluetooth Adapter State.
29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * States:
30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      {@link OnState} : Bluetooth is on at this state
31ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      {@link OffState}: Bluetooth is off at this state. This is the initial
32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      state.
33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      {@link PendingCommandState} : An enable / disable operation is pending.
34ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * TODO(BT): Add per process on state.
35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshfinal class AdapterState extends StateMachine {
3834e323baafb5563c3874f95847ec544faf6923f8Matthew Xie    private static final boolean DBG = true;
39f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private static final boolean VDBG = true;
40ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private static final String TAG = "BluetoothAdapterState";
41ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
42f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BLE_TURN_ON = 0;
43ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    static final int USER_TURN_ON = 1;
44f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BREDR_STARTED=2;
4531ba132491053bc86d419a7d51fc04af3299c076fredc    static final int ENABLED_READY = 3;
46f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BLE_STARTED=4;
47ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
4831ba132491053bc86d419a7d51fc04af3299c076fredc    static final int USER_TURN_OFF = 20;
4931ba132491053bc86d419a7d51fc04af3299c076fredc    static final int BEGIN_DISABLE = 21;
5031ba132491053bc86d419a7d51fc04af3299c076fredc    static final int ALL_DEVICES_DISCONNECTED = 22;
51f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BLE_TURN_OFF = 23;
5274ae04c73312403e89db0f8e9bd9601d403b4783fredc
5331ba132491053bc86d419a7d51fc04af3299c076fredc    static final int DISABLED = 24;
54f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BLE_STOPPED=25;
55f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BREDR_STOPPED = 26;
56ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
57f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BREDR_START_TIMEOUT = 100;
5831ba132491053bc86d419a7d51fc04af3299c076fredc    static final int ENABLE_TIMEOUT = 101;
5931ba132491053bc86d419a7d51fc04af3299c076fredc    static final int DISABLE_TIMEOUT = 103;
60f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BLE_STOP_TIMEOUT = 104;
6157a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie    static final int SET_SCAN_MODE_TIMEOUT = 105;
62f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BLE_START_TIMEOUT = 106;
63f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    static final int BREDR_STOP_TIMEOUT = 107;
6431ba132491053bc86d419a7d51fc04af3299c076fredc
6531ba132491053bc86d419a7d51fc04af3299c076fredc    static final int USER_TURN_OFF_DELAY_MS=500;
6631ba132491053bc86d419a7d51fc04af3299c076fredc
6731ba132491053bc86d419a7d51fc04af3299c076fredc    //TODO: tune me
68f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private static final int ENABLE_TIMEOUT_DELAY = 12000;
6931ba132491053bc86d419a7d51fc04af3299c076fredc    private static final int DISABLE_TIMEOUT_DELAY = 8000;
70f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private static final int BREDR_START_TIMEOUT_DELAY = 4000;
71f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    //BLE_START_TIMEOUT can happen quickly as it just a start gattservice
72f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private static final int BLE_START_TIMEOUT_DELAY = 2000; //To start GattService
73f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private static final int BLE_STOP_TIMEOUT_DELAY = 2000;
74f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    //BREDR_STOP_TIMEOUT can < STOP_TIMEOUT
75f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private static final int BREDR_STOP_TIMEOUT_DELAY = 4000;
7631ba132491053bc86d419a7d51fc04af3299c076fredc    private static final int PROPERTY_OP_DELAY =2000;
776654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private AdapterService mAdapterService;
786654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private AdapterProperties mAdapterProperties;
79ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private PendingCommandState mPendingCommandState = new PendingCommandState();
80ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private OnState mOnState = new OnState();
81ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private OffState mOffState = new OffState();
82f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private BleOnState mBleOnState = new BleOnState();
83ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
8431ba132491053bc86d419a7d51fc04af3299c076fredc    public boolean isTurningOn() {
855b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach        return mPendingCommandState.isTurningOn();
86b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
8731ba132491053bc86d419a7d51fc04af3299c076fredc
88f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    public boolean isBleTurningOn() {
895b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach        return mPendingCommandState.isBleTurningOn();
90f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    }
91f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
92f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    public boolean isBleTurningOff() {
935b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach        return mPendingCommandState.isBleTurningOff();
94f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    }
95f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
9631ba132491053bc86d419a7d51fc04af3299c076fredc    public boolean isTurningOff() {
975b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach        return mPendingCommandState.isTurningOff();
9831ba132491053bc86d419a7d51fc04af3299c076fredc    }
9931ba132491053bc86d419a7d51fc04af3299c076fredc
1006893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville    private AdapterState(AdapterService service, AdapterProperties adapterProperties) {
101ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        super("BluetoothAdapterState:");
102ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mOnState);
103f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        addState(mBleOnState);
104ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mOffState);
105ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mPendingCommandState);
106ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterService = service;
107ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterProperties = adapterProperties;
1086654f5c903de510a70f9e72cd5ad7837b615d93ffredc        setInitialState(mOffState);
1096654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1106654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1116893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville    public static AdapterState make(AdapterService service, AdapterProperties adapterProperties) {
112f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        Log.d(TAG, "make() - Creating AdapterState");
1136893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        AdapterState as = new AdapterState(service, adapterProperties);
1146893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        as.start();
1156893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville        return as;
1166893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville    }
11715d36984a79d6e35c659edb0efdf929f0b526bd5Fred
11815d36984a79d6e35c659edb0efdf929f0b526bd5Fred    public void doQuit() {
11915d36984a79d6e35c659edb0efdf929f0b526bd5Fred        quitNow();
12015d36984a79d6e35c659edb0efdf929f0b526bd5Fred    }
12115d36984a79d6e35c659edb0efdf929f0b526bd5Fred
1226654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public void cleanup() {
1233fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan        if(mAdapterProperties != null)
1243fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan            mAdapterProperties = null;
1253fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan        if(mAdapterService != null)
1263fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan            mAdapterService = null;
127ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
128ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
129ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class OffState extends State {
130ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
131ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
13231ba132491053bc86d419a7d51fc04af3299c076fredc            infoLog("Entering OffState");
133ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
134ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
135ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
136ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
1370eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            AdapterService adapterService = mAdapterService;
1380eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            if (adapterService == null) {
139f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                errorLog("Received message in OffState after cleanup: " + msg.what);
1400eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                return false;
1410eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            }
142f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
143f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            debugLog("Current state: OFF, message: " + msg.what);
144f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
145f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            switch(msg.what) {
146f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora               case BLE_TURN_ON:
147f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_TURNING_ON);
148f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   mPendingCommandState.setBleTurningOn(true);
149f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   transitionTo(mPendingCommandState);
150f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
151f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   adapterService.BleOnProcessStart();
152f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   break;
153f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
154f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora               case USER_TURN_OFF:
155f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   //TODO: Handle case of service started and stopped without enable
156f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   break;
157f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
158f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora               default:
159f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   return false;
160f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            }
161f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            return true;
162f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        }
163f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    }
164f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
165f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private class BleOnState extends State {
166f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        @Override
167f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        public void enter() {
168f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            infoLog("Entering BleOnState");
169f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        }
170f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
171f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        @Override
172f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        public boolean processMessage(Message msg) {
173f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
174f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            AdapterService adapterService = mAdapterService;
175f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            AdapterProperties adapterProperties = mAdapterProperties;
176f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            if ((adapterService == null) || (adapterProperties == null)) {
177f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                errorLog("Received message in BleOnState after cleanup: " + msg.what);
178f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                return false;
179f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            }
180f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
181f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            debugLog("Current state: BLE ON, message: " + msg.what);
182f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
183ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch(msg.what) {
184ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               case USER_TURN_ON:
1854852c5686229f1014e9851f4e9a3a19547581b45fredc                   notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_ON);
18631ba132491053bc86d419a7d51fc04af3299c076fredc                   mPendingCommandState.setTurningOn(true);
18731ba132491053bc86d419a7d51fc04af3299c076fredc                   transitionTo(mPendingCommandState);
188f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   sendMessageDelayed(BREDR_START_TIMEOUT, BREDR_START_TIMEOUT_DELAY);
189f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   adapterService.startCoreServices();
190ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   break;
191f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
192ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               case USER_TURN_OFF:
193f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_TURNING_OFF);
194f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   mPendingCommandState.setBleTurningOff(true);
195f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   adapterProperties.onBleDisable();
196f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   transitionTo(mPendingCommandState);
197f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   sendMessageDelayed(DISABLE_TIMEOUT, DISABLE_TIMEOUT_DELAY);
198f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   boolean ret = adapterService.disableNative();
199f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   if (!ret) {
200f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        removeMessages(DISABLE_TIMEOUT);
201f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        errorLog("Error while calling disableNative");
202f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        //FIXME: what about post enable services
203f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        mPendingCommandState.setBleTurningOff(false);
204f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_ON);
205f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                   }
206ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   break;
207f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
208ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               default:
209ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   return false;
210ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
211ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
212ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
213ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
214ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
215ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class OnState extends State {
216ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
217ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
218f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            infoLog("Entering OnState");
219f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
2200eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            AdapterService adapterService = mAdapterService;
2210eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            if (adapterService == null) {
222f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                errorLog("Entered OnState after cleanup");
2230eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                return;
2240eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            }
225c050578e447a96272daa7717de0ecf913b94e719venkata Jagadeesh            adapterService.updateUuids();
226ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
227ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
228ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
229ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
2300eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            AdapterProperties adapterProperties = mAdapterProperties;
2310eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            if (adapterProperties == null) {
232f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                errorLog("Received message in OnState after cleanup: " + msg.what);
2330eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                return false;
2340eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            }
23515d36984a79d6e35c659edb0efdf929f0b526bd5Fred
236f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            debugLog("Current state: ON, message: " + msg.what);
237f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
238ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch(msg.what) {
239f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora               case BLE_TURN_OFF:
2404852c5686229f1014e9851f4e9a3a19547581b45fredc                   notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_OFF);
24131ba132491053bc86d419a7d51fc04af3299c076fredc                   mPendingCommandState.setTurningOff(true);
24231ba132491053bc86d419a7d51fc04af3299c076fredc                   transitionTo(mPendingCommandState);
24331ba132491053bc86d419a7d51fc04af3299c076fredc
244d570893c5ec3bc9fd1860aa0355c550d3a51f8ddKausik Sinnaswamy                   // Invoke onBluetoothDisable which shall trigger a
245d570893c5ec3bc9fd1860aa0355c550d3a51f8ddKausik Sinnaswamy                   // setScanMode to SCAN_MODE_NONE
24657a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie                   Message m = obtainMessage(SET_SCAN_MODE_TIMEOUT);
24731ba132491053bc86d419a7d51fc04af3299c076fredc                   sendMessageDelayed(m, PROPERTY_OP_DELAY);
2480eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                   adapterProperties.onBluetoothDisable();
249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   break;
25031ba132491053bc86d419a7d51fc04af3299c076fredc
251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               case USER_TURN_ON:
252ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   break;
253f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               default:
255ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   return false;
256ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
257ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
258ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
259ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
260ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
261ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class PendingCommandState extends State {
26231ba132491053bc86d419a7d51fc04af3299c076fredc        private boolean mIsTurningOn;
26331ba132491053bc86d419a7d51fc04af3299c076fredc        private boolean mIsTurningOff;
264f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        private boolean mIsBleTurningOn;
265f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        private boolean mIsBleTurningOff;
26631ba132491053bc86d419a7d51fc04af3299c076fredc
267ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
268f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            infoLog("Entering PendingCommandState");
26931ba132491053bc86d419a7d51fc04af3299c076fredc        }
27031ba132491053bc86d419a7d51fc04af3299c076fredc
27131ba132491053bc86d419a7d51fc04af3299c076fredc        public void setTurningOn(boolean isTurningOn) {
27231ba132491053bc86d419a7d51fc04af3299c076fredc            mIsTurningOn = isTurningOn;
27331ba132491053bc86d419a7d51fc04af3299c076fredc        }
27431ba132491053bc86d419a7d51fc04af3299c076fredc
27531ba132491053bc86d419a7d51fc04af3299c076fredc        public boolean isTurningOn() {
27631ba132491053bc86d419a7d51fc04af3299c076fredc            return mIsTurningOn;
27731ba132491053bc86d419a7d51fc04af3299c076fredc        }
27831ba132491053bc86d419a7d51fc04af3299c076fredc
27931ba132491053bc86d419a7d51fc04af3299c076fredc        public void setTurningOff(boolean isTurningOff) {
28031ba132491053bc86d419a7d51fc04af3299c076fredc            mIsTurningOff = isTurningOff;
28131ba132491053bc86d419a7d51fc04af3299c076fredc        }
28231ba132491053bc86d419a7d51fc04af3299c076fredc
28331ba132491053bc86d419a7d51fc04af3299c076fredc        public boolean isTurningOff() {
28431ba132491053bc86d419a7d51fc04af3299c076fredc            return mIsTurningOff;
28531ba132491053bc86d419a7d51fc04af3299c076fredc        }
28631ba132491053bc86d419a7d51fc04af3299c076fredc
287f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        public void setBleTurningOn(boolean isBleTurningOn) {
288f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            mIsBleTurningOn = isBleTurningOn;
289f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        }
290f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
291f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        public boolean isBleTurningOn() {
292f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            return mIsBleTurningOn;
293f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        }
294f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
295f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        public void setBleTurningOff(boolean isBleTurningOff) {
296f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            mIsBleTurningOff = isBleTurningOff;
297f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        }
298f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
299f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        public boolean isBleTurningOff() {
300f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            return mIsBleTurningOff;
301f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        }
302f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
303ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
304ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
30515d36984a79d6e35c659edb0efdf929f0b526bd5Fred
3065b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach            /* Cache current states */
3075b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach            /* TODO(eisenbach): Not sure why this is done at all.
3085b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach             * Seems like the mIs* variables should be protected,
3095b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach             * or really, removed. Which reminds me: This file needs
3105b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach             * a serious refactor...*/
3115b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach            boolean isTurningOn = isTurningOn();
31231ba132491053bc86d419a7d51fc04af3299c076fredc            boolean isTurningOff = isTurningOff();
313f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            boolean isBleTurningOn = isBleTurningOn();
314f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            boolean isBleTurningOff = isBleTurningOff();
31515d36984a79d6e35c659edb0efdf929f0b526bd5Fred
3165b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach            logTransientStates();
3175b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach
3180eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            AdapterService adapterService = mAdapterService;
3190eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            AdapterProperties adapterProperties = mAdapterProperties;
3200eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            if ((adapterService == null) || (adapterProperties == null)) {
321f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                errorLog("Received message in PendingCommandState after cleanup: " + msg.what);
3220eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                return false;
3230eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            }
3240eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu
325f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            debugLog("Current state: PENDING_COMMAND, message: " + msg.what);
326f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
327ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch (msg.what) {
328ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case USER_TURN_ON:
329f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    if (isBleTurningOff || isTurningOff) { //TODO:do we need to send it after ble turn off also??
330f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        infoLog("Deferring USER_TURN_ON request...");
33131ba132491053bc86d419a7d51fc04af3299c076fredc                        deferMessage(msg);
33231ba132491053bc86d419a7d51fc04af3299c076fredc                    }
33331ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
334f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
335ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case USER_TURN_OFF:
336f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    if (isTurningOn || isBleTurningOn) {
337f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        infoLog("Deferring USER_TURN_OFF request...");
338f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        deferMessage(msg);
339f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    }
340f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    break;
341f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
342f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BLE_TURN_ON:
343f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    if (isTurningOff || isBleTurningOff) {
344f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        infoLog("Deferring BLE_TURN_ON request...");
345f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        deferMessage(msg);
346f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    }
347f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    break;
348f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
349f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BLE_TURN_OFF:
350f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    if (isTurningOn || isBleTurningOn) {
351f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        infoLog("Deferring BLE_TURN_OFF request...");
35231ba132491053bc86d419a7d51fc04af3299c076fredc                        deferMessage(msg);
35331ba132491053bc86d419a7d51fc04af3299c076fredc                    }
354ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
355f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
356f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BLE_STARTED:
35731ba132491053bc86d419a7d51fc04af3299c076fredc                    //Remove start timeout
358f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    removeMessages(BLE_START_TIMEOUT);
35931ba132491053bc86d419a7d51fc04af3299c076fredc
36031ba132491053bc86d419a7d51fc04af3299c076fredc                    //Enable
361c63ef51ba5f9d355239959bcfe8803987adb1f38Ajay Panicker                    boolean isGuest = UserManager.get(mAdapterService).isGuestUser();
362c63ef51ba5f9d355239959bcfe8803987adb1f38Ajay Panicker                    if (!adapterService.enableNative(isGuest)) {
363f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        errorLog("Error while turning Bluetooth on");
3644852c5686229f1014e9851f4e9a3a19547581b45fredc                        notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
36531ba132491053bc86d419a7d51fc04af3299c076fredc                        transitionTo(mOffState);
36631ba132491053bc86d419a7d51fc04af3299c076fredc                    } else {
36731ba132491053bc86d419a7d51fc04af3299c076fredc                        sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY);
36831ba132491053bc86d419a7d51fc04af3299c076fredc                    }
36931ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
37031ba132491053bc86d419a7d51fc04af3299c076fredc
371f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BREDR_STARTED:
372f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    //Remove start timeout
373f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    removeMessages(BREDR_START_TIMEOUT);
3740eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                    adapterProperties.onBluetoothReady();
37531ba132491053bc86d419a7d51fc04af3299c076fredc                    mPendingCommandState.setTurningOn(false);
37631ba132491053bc86d419a7d51fc04af3299c076fredc                    transitionTo(mOnState);
3774852c5686229f1014e9851f4e9a3a19547581b45fredc                    notifyAdapterStateChange(BluetoothAdapter.STATE_ON);
37831ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
37931ba132491053bc86d419a7d51fc04af3299c076fredc
380f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case ENABLED_READY:
381f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    removeMessages(ENABLE_TIMEOUT);
382f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    mPendingCommandState.setBleTurningOn(false);
383f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    transitionTo(mBleOnState);
384f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_ON);
385f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    break;
386f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
38757a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie                case SET_SCAN_MODE_TIMEOUT:
388f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                     warningLog("Timeout while setting scan mode. Continuing with disable...");
38957a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie                     //Fall through
390f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BEGIN_DISABLE:
39157a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie                    removeMessages(SET_SCAN_MODE_TIMEOUT);
392f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    sendMessageDelayed(BREDR_STOP_TIMEOUT, BREDR_STOP_TIMEOUT_DELAY);
393f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    adapterService.stopProfileServices();
394ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
395f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
396ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case DISABLED:
397ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                    if (isTurningOn) {
398ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                        removeMessages(ENABLE_TIMEOUT);
399f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        errorLog("Error enabling Bluetooth - hardware init failed?");
400ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                        mPendingCommandState.setTurningOn(false);
401ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                        transitionTo(mOffState);
4020eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu                        adapterService.stopProfileServices();
403ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                        notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
404ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                        break;
405ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao                    }
40631ba132491053bc86d419a7d51fc04af3299c076fredc                    removeMessages(DISABLE_TIMEOUT);
407f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    sendMessageDelayed(BLE_STOP_TIMEOUT, BLE_STOP_TIMEOUT_DELAY);
408f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    if (adapterService.stopGattProfileService()) {
409f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                        debugLog("Stopping Gatt profile services that were post enabled");
41031ba132491053bc86d419a7d51fc04af3299c076fredc                        break;
41131ba132491053bc86d419a7d51fc04af3299c076fredc                    }
41274ae04c73312403e89db0f8e9bd9601d403b4783fredc                    //Fall through if no services or services already stopped
413f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BLE_STOPPED:
414f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    removeMessages(BLE_STOP_TIMEOUT);
415f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    setBleTurningOff(false);
41631ba132491053bc86d419a7d51fc04af3299c076fredc                    transitionTo(mOffState);
4174852c5686229f1014e9851f4e9a3a19547581b45fredc                    notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
41831ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
419f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
420f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BREDR_STOPPED:
421f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    removeMessages(BREDR_STOP_TIMEOUT);
422f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    setTurningOff(false);
423f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    transitionTo(mBleOnState);
424f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_ON);
425f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    break;
426f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
427f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BLE_START_TIMEOUT:
428f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    errorLog("Error enabling Bluetooth (BLE start timeout)");
429f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    mPendingCommandState.setBleTurningOn(false);
430ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    transitionTo(mOffState);
4314852c5686229f1014e9851f4e9a3a19547581b45fredc                    notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
432ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
433f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
434f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BREDR_START_TIMEOUT:
435f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    errorLog("Error enabling Bluetooth (start timeout)");
43631ba132491053bc86d419a7d51fc04af3299c076fredc                    mPendingCommandState.setTurningOn(false);
4374e34b45bdc8cdd1c744e46341419b4f838d82a5aSrinu Jella                    adapterService.stopProfileServices();
438f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    transitionTo(mBleOnState);
439f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_ON);
440f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    break;
441f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
442f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case ENABLE_TIMEOUT:
443f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    errorLog("Error enabling Bluetooth (enable timeout)");
444f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    mPendingCommandState.setBleTurningOn(false);
445ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    transitionTo(mOffState);
4464e34b45bdc8cdd1c744e46341419b4f838d82a5aSrinu Jella                    adapterService.stopProfileServices();
4474e34b45bdc8cdd1c744e46341419b4f838d82a5aSrinu Jella                    adapterService.stopGattProfileService();
4484852c5686229f1014e9851f4e9a3a19547581b45fredc                    notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
44931ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
450f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
451f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BREDR_STOP_TIMEOUT:
452f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    errorLog("Error stopping Bluetooth profiles (stop timeout)");
453f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    mPendingCommandState.setTurningOff(false);
454f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    transitionTo(mBleOnState);
455f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_ON);
456f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    break;
457f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
458f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                case BLE_STOP_TIMEOUT:
459f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    errorLog("Error stopping Bluetooth profiles (BLE stop timeout)");
46031ba132491053bc86d419a7d51fc04af3299c076fredc                    mPendingCommandState.setTurningOff(false);
46131ba132491053bc86d419a7d51fc04af3299c076fredc                    transitionTo(mOffState);
462f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
46331ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
464f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
46531ba132491053bc86d419a7d51fc04af3299c076fredc                case DISABLE_TIMEOUT:
466f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora                    errorLog("Error disabling Bluetooth (disable timeout)");
46768cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                    if (isTurningOn)
46868cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                        mPendingCommandState.setTurningOn(false);
46968cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                    adapterService.stopProfileServices();
47068cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                    adapterService.stopGattProfileService();
47131ba132491053bc86d419a7d51fc04af3299c076fredc                    mPendingCommandState.setTurningOff(false);
47268cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                    setBleTurningOff(false);
47368cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                    transitionTo(mOffState);
47468cbac9663a8cac0416bc81968f5f543f88b741cPavlin Radoslavov                    notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
475ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
476f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
477ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                default:
478ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    return false;
479ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
480ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
481ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
4825b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach
4835b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach        private void logTransientStates() {
4845b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach            StringBuilder sb = new StringBuilder();
4855b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach            sb.append("PendingCommand - transient state(s):");
4865b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach
4875b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach            if (isTurningOn()) sb.append(" isTurningOn");
4885b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach            if (isTurningOff()) sb.append(" isTurningOff");
4895b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach            if (isBleTurningOn()) sb.append(" isBleTurningOn");
4905b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach            if (isBleTurningOff()) sb.append(" isBleTurningOff");
4915b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach
4925b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach            verboseLog(sb.toString());
4935b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach        }
494ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
495ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
4964852c5686229f1014e9851f4e9a3a19547581b45fredc    private void notifyAdapterStateChange(int newState) {
4970eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        AdapterService adapterService = mAdapterService;
4980eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        AdapterProperties adapterProperties = mAdapterProperties;
4990eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        if ((adapterService == null) || (adapterProperties == null)) {
500f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora            errorLog("notifyAdapterStateChange after cleanup:" + newState);
5010eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu            return;
5020eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        }
5030eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu
5040eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        int oldState = adapterProperties.getState();
5050eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        adapterProperties.setState(newState);
5064852c5686229f1014e9851f4e9a3a19547581b45fredc        infoLog("Bluetooth adapter state changed: " + oldState + "-> " + newState);
5070eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu        adapterService.updateAdapterState(oldState, newState);
508ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
509ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
510ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    void stateChangeCallback(int status) {
511ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (status == AbstractionLayer.BT_STATE_OFF) {
512ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            sendMessage(DISABLED);
513f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
514ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        } else if (status == AbstractionLayer.BT_STATE_ON) {
515ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh            // We should have got the property change for adapter and remote devices.
516ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh            sendMessage(ENABLED_READY);
517f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
518ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        } else {
519ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            errorLog("Incorrect status in stateChangeCallback");
520ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
521ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
522ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
523ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void infoLog(String msg) {
524ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (DBG) Log.i(TAG, msg);
525ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
526ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
527f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private void debugLog(String msg) {
528f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        if (DBG) Log.d(TAG, msg);
529f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    }
530f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
531f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private void warningLog(String msg) {
5325b0dcf64aa76cb7ab8a50b033ef4e9ce23d3f4aaAndre Eisenbach        if (DBG) Log.w(TAG, msg);
533f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    }
534f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
535f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    private void verboseLog(String msg) {
536f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora        if (VDBG) Log.v(TAG, msg);
537f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora    }
538f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora
539ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void errorLog(String msg) {
540ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Log.e(TAG, msg);
541ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
54215d36984a79d6e35c659edb0efdf929f0b526bd5Fred
543ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
544