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; 23ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.util.Log; 24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.State; 26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.StateMachine; 27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/** 29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * This state machine handles Bluetooth Adapter State. 30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * States: 31ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * {@link OnState} : Bluetooth is on at this state 32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * {@link OffState}: Bluetooth is off at this state. This is the initial 33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * state. 34ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * {@link PendingCommandState} : An enable / disable operation is pending. 35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * TODO(BT): Add per process on state. 36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */ 37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 38ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshfinal class AdapterState extends StateMachine { 3934e323baafb5563c3874f95847ec544faf6923f8Matthew Xie private static final boolean DBG = true; 4034e323baafb5563c3874f95847ec544faf6923f8Matthew Xie private static final boolean VDBG = false; 41ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private static final String TAG = "BluetoothAdapterState"; 42ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 43ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh static final int USER_TURN_ON = 1; 4431ba132491053bc86d419a7d51fc04af3299c076fredc static final int STARTED=2; 4531ba132491053bc86d419a7d51fc04af3299c076fredc static final int ENABLED_READY = 3; 46ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 4731ba132491053bc86d419a7d51fc04af3299c076fredc static final int USER_TURN_OFF = 20; 4831ba132491053bc86d419a7d51fc04af3299c076fredc static final int BEGIN_DISABLE = 21; 4931ba132491053bc86d419a7d51fc04af3299c076fredc static final int ALL_DEVICES_DISCONNECTED = 22; 5074ae04c73312403e89db0f8e9bd9601d403b4783fredc 5131ba132491053bc86d419a7d51fc04af3299c076fredc static final int DISABLED = 24; 5231ba132491053bc86d419a7d51fc04af3299c076fredc static final int STOPPED=25; 53ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 5431ba132491053bc86d419a7d51fc04af3299c076fredc static final int START_TIMEOUT = 100; 5531ba132491053bc86d419a7d51fc04af3299c076fredc static final int ENABLE_TIMEOUT = 101; 5631ba132491053bc86d419a7d51fc04af3299c076fredc static final int DISABLE_TIMEOUT = 103; 5731ba132491053bc86d419a7d51fc04af3299c076fredc static final int STOP_TIMEOUT = 104; 5857a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie static final int SET_SCAN_MODE_TIMEOUT = 105; 5931ba132491053bc86d419a7d51fc04af3299c076fredc 6031ba132491053bc86d419a7d51fc04af3299c076fredc static final int USER_TURN_OFF_DELAY_MS=500; 6131ba132491053bc86d419a7d51fc04af3299c076fredc 6231ba132491053bc86d419a7d51fc04af3299c076fredc //TODO: tune me 6331ba132491053bc86d419a7d51fc04af3299c076fredc private static final int ENABLE_TIMEOUT_DELAY = 8000; 6431ba132491053bc86d419a7d51fc04af3299c076fredc private static final int DISABLE_TIMEOUT_DELAY = 8000; 6531ba132491053bc86d419a7d51fc04af3299c076fredc private static final int START_TIMEOUT_DELAY = 5000; 6631ba132491053bc86d419a7d51fc04af3299c076fredc private static final int STOP_TIMEOUT_DELAY = 5000; 6731ba132491053bc86d419a7d51fc04af3299c076fredc private static final int PROPERTY_OP_DELAY =2000; 686654f5c903de510a70f9e72cd5ad7837b615d93ffredc private AdapterService mAdapterService; 696654f5c903de510a70f9e72cd5ad7837b615d93ffredc private AdapterProperties mAdapterProperties; 70ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private PendingCommandState mPendingCommandState = new PendingCommandState(); 71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private OnState mOnState = new OnState(); 72ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private OffState mOffState = new OffState(); 73ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 7431ba132491053bc86d419a7d51fc04af3299c076fredc public boolean isTurningOn() { 7531ba132491053bc86d419a7d51fc04af3299c076fredc boolean isTurningOn= mPendingCommandState.isTurningOn(); 7634e323baafb5563c3874f95847ec544faf6923f8Matthew Xie if (VDBG) Log.d(TAG,"isTurningOn()=" + isTurningOn); 7731ba132491053bc86d419a7d51fc04af3299c076fredc return isTurningOn; 78b5cc776c9353a203cdde97e62b25f05d9633d14cfredc } 7931ba132491053bc86d419a7d51fc04af3299c076fredc 8031ba132491053bc86d419a7d51fc04af3299c076fredc public boolean isTurningOff() { 8131ba132491053bc86d419a7d51fc04af3299c076fredc boolean isTurningOff= mPendingCommandState.isTurningOff(); 8234e323baafb5563c3874f95847ec544faf6923f8Matthew Xie if (VDBG) Log.d(TAG,"isTurningOff()=" + isTurningOff); 8331ba132491053bc86d419a7d51fc04af3299c076fredc return isTurningOff; 8431ba132491053bc86d419a7d51fc04af3299c076fredc } 8531ba132491053bc86d419a7d51fc04af3299c076fredc 866893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville private AdapterState(AdapterService service, AdapterProperties adapterProperties) { 87ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh super("BluetoothAdapterState:"); 88ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addState(mOnState); 89ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addState(mOffState); 90ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh addState(mPendingCommandState); 91ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh mAdapterService = service; 92ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh mAdapterProperties = adapterProperties; 936654f5c903de510a70f9e72cd5ad7837b615d93ffredc setInitialState(mOffState); 946654f5c903de510a70f9e72cd5ad7837b615d93ffredc } 956654f5c903de510a70f9e72cd5ad7837b615d93ffredc 966893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville public static AdapterState make(AdapterService service, AdapterProperties adapterProperties) { 976893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville Log.d(TAG, "make"); 986893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville AdapterState as = new AdapterState(service, adapterProperties); 996893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville as.start(); 1006893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville return as; 1016893668d1ccf0cc6361ef31ace52fedc2e37e35aWink Saville } 10215d36984a79d6e35c659edb0efdf929f0b526bd5Fred 10315d36984a79d6e35c659edb0efdf929f0b526bd5Fred public void doQuit() { 10415d36984a79d6e35c659edb0efdf929f0b526bd5Fred quitNow(); 10515d36984a79d6e35c659edb0efdf929f0b526bd5Fred } 10615d36984a79d6e35c659edb0efdf929f0b526bd5Fred 1076654f5c903de510a70f9e72cd5ad7837b615d93ffredc public void cleanup() { 1083fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan if(mAdapterProperties != null) 1093fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan mAdapterProperties = null; 1103fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan if(mAdapterService != null) 1113fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan mAdapterService = null; 112ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 113ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 114ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private class OffState extends State { 115ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh @Override 116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public void enter() { 11731ba132491053bc86d419a7d51fc04af3299c076fredc infoLog("Entering OffState"); 118ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 119ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 120ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh @Override 121ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public boolean processMessage(Message msg) { 1220eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu AdapterService adapterService = mAdapterService; 1230eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu if (adapterService == null) { 1240eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu Log.e(TAG,"receive message at OffState after cleanup:" + 1250eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu msg.what); 1260eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu return false; 1270eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu } 128ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh switch(msg.what) { 129ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case USER_TURN_ON: 13057a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie if (DBG) Log.d(TAG,"CURRENT_STATE=OFF, MESSAGE = USER_TURN_ON"); 1314852c5686229f1014e9851f4e9a3a19547581b45fredc notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_ON); 13231ba132491053bc86d419a7d51fc04af3299c076fredc mPendingCommandState.setTurningOn(true); 13331ba132491053bc86d419a7d51fc04af3299c076fredc transitionTo(mPendingCommandState); 13431ba132491053bc86d419a7d51fc04af3299c076fredc sendMessageDelayed(START_TIMEOUT, START_TIMEOUT_DELAY); 1350eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu adapterService.processStart(); 136ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 137ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case USER_TURN_OFF: 13857a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie if (DBG) Log.d(TAG,"CURRENT_STATE=OFF, MESSAGE = USER_TURN_OFF"); 13957a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie //TODO: Handle case of service started and stopped without enable 140ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 141ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh default: 14231ba132491053bc86d419a7d51fc04af3299c076fredc if (DBG) Log.d(TAG,"ERROR: UNEXPECTED MESSAGE: CURRENT_STATE=OFF, MESSAGE = " + msg.what ); 143ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return false; 144ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 145ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 146ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 147ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 148ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 149ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private class OnState extends State { 150ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh @Override 151ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public void enter() { 152ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh infoLog("Entering On State"); 1530eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu AdapterService adapterService = mAdapterService; 1540eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu if (adapterService == null) { 1550eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu Log.e(TAG,"enter OnState after cleanup"); 1560eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu return; 1570eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu } 1580eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu adapterService.autoConnect(); 159ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 160ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 161ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh @Override 162ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public boolean processMessage(Message msg) { 1630eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu AdapterProperties adapterProperties = mAdapterProperties; 1640eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu if (adapterProperties == null) { 1650eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu Log.e(TAG,"receive message at OnState after cleanup:" + 1660eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu msg.what); 1670eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu return false; 1680eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu } 16915d36984a79d6e35c659edb0efdf929f0b526bd5Fred 170ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh switch(msg.what) { 171ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case USER_TURN_OFF: 17257a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie if (DBG) Log.d(TAG,"CURRENT_STATE=ON, MESSAGE = USER_TURN_OFF"); 1734852c5686229f1014e9851f4e9a3a19547581b45fredc notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_OFF); 17431ba132491053bc86d419a7d51fc04af3299c076fredc mPendingCommandState.setTurningOff(true); 17531ba132491053bc86d419a7d51fc04af3299c076fredc transitionTo(mPendingCommandState); 17631ba132491053bc86d419a7d51fc04af3299c076fredc 177d570893c5ec3bc9fd1860aa0355c550d3a51f8ddKausik Sinnaswamy // Invoke onBluetoothDisable which shall trigger a 178d570893c5ec3bc9fd1860aa0355c550d3a51f8ddKausik Sinnaswamy // setScanMode to SCAN_MODE_NONE 17957a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie Message m = obtainMessage(SET_SCAN_MODE_TIMEOUT); 18031ba132491053bc86d419a7d51fc04af3299c076fredc sendMessageDelayed(m, PROPERTY_OP_DELAY); 1810eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu adapterProperties.onBluetoothDisable(); 182ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 18331ba132491053bc86d419a7d51fc04af3299c076fredc 184ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case USER_TURN_ON: 18557a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie if (DBG) Log.d(TAG,"CURRENT_STATE=ON, MESSAGE = USER_TURN_ON"); 18631ba132491053bc86d419a7d51fc04af3299c076fredc Log.i(TAG,"Bluetooth already ON, ignoring USER_TURN_ON"); 187ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 188ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh default: 18931ba132491053bc86d419a7d51fc04af3299c076fredc if (DBG) Log.d(TAG,"ERROR: UNEXPECTED MESSAGE: CURRENT_STATE=ON, MESSAGE = " + msg.what ); 190ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return false; 191ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 192ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 193ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 194ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 195ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 196ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private class PendingCommandState extends State { 19731ba132491053bc86d419a7d51fc04af3299c076fredc private boolean mIsTurningOn; 19831ba132491053bc86d419a7d51fc04af3299c076fredc private boolean mIsTurningOff; 19931ba132491053bc86d419a7d51fc04af3299c076fredc 200ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public void enter() { 20131ba132491053bc86d419a7d51fc04af3299c076fredc infoLog("Entering PendingCommandState State: isTurningOn()=" + isTurningOn() + ", isTurningOff()=" + isTurningOff()); 20231ba132491053bc86d419a7d51fc04af3299c076fredc } 20331ba132491053bc86d419a7d51fc04af3299c076fredc 20431ba132491053bc86d419a7d51fc04af3299c076fredc public void setTurningOn(boolean isTurningOn) { 20531ba132491053bc86d419a7d51fc04af3299c076fredc mIsTurningOn = isTurningOn; 20631ba132491053bc86d419a7d51fc04af3299c076fredc } 20731ba132491053bc86d419a7d51fc04af3299c076fredc 20831ba132491053bc86d419a7d51fc04af3299c076fredc public boolean isTurningOn() { 20931ba132491053bc86d419a7d51fc04af3299c076fredc return mIsTurningOn; 21031ba132491053bc86d419a7d51fc04af3299c076fredc } 21131ba132491053bc86d419a7d51fc04af3299c076fredc 21231ba132491053bc86d419a7d51fc04af3299c076fredc public void setTurningOff(boolean isTurningOff) { 21331ba132491053bc86d419a7d51fc04af3299c076fredc mIsTurningOff = isTurningOff; 21431ba132491053bc86d419a7d51fc04af3299c076fredc } 21531ba132491053bc86d419a7d51fc04af3299c076fredc 21631ba132491053bc86d419a7d51fc04af3299c076fredc public boolean isTurningOff() { 21731ba132491053bc86d419a7d51fc04af3299c076fredc return mIsTurningOff; 21831ba132491053bc86d419a7d51fc04af3299c076fredc } 21931ba132491053bc86d419a7d51fc04af3299c076fredc 220ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh @Override 221ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh public boolean processMessage(Message msg) { 22215d36984a79d6e35c659edb0efdf929f0b526bd5Fred 22331ba132491053bc86d419a7d51fc04af3299c076fredc boolean isTurningOn= isTurningOn(); 22431ba132491053bc86d419a7d51fc04af3299c076fredc boolean isTurningOff = isTurningOff(); 22515d36984a79d6e35c659edb0efdf929f0b526bd5Fred 2260eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu AdapterService adapterService = mAdapterService; 2270eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu AdapterProperties adapterProperties = mAdapterProperties; 2280eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu if ((adapterService == null) || (adapterProperties == null)) { 2290eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu Log.e(TAG,"receive message at Pending State after cleanup:" + 2300eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu msg.what); 2310eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu return false; 2320eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu } 2330eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu 234ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh switch (msg.what) { 235ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case USER_TURN_ON: 23657a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = USER_TURN_ON" 23731ba132491053bc86d419a7d51fc04af3299c076fredc + ", isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); 23831ba132491053bc86d419a7d51fc04af3299c076fredc if (isTurningOn) { 23931ba132491053bc86d419a7d51fc04af3299c076fredc Log.i(TAG,"CURRENT_STATE=PENDING: Alreadying turning on bluetooth... Ignoring USER_TURN_ON..."); 24031ba132491053bc86d419a7d51fc04af3299c076fredc } else { 24131ba132491053bc86d419a7d51fc04af3299c076fredc Log.i(TAG,"CURRENT_STATE=PENDING: Deferring request USER_TURN_ON"); 24231ba132491053bc86d419a7d51fc04af3299c076fredc deferMessage(msg); 24331ba132491053bc86d419a7d51fc04af3299c076fredc } 24431ba132491053bc86d419a7d51fc04af3299c076fredc break; 245ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case USER_TURN_OFF: 24657a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = USER_TURN_ON" 24731ba132491053bc86d419a7d51fc04af3299c076fredc + ", isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); 24831ba132491053bc86d419a7d51fc04af3299c076fredc if (isTurningOff) { 24931ba132491053bc86d419a7d51fc04af3299c076fredc Log.i(TAG,"CURRENT_STATE=PENDING: Alreadying turning off bluetooth... Ignoring USER_TURN_OFF..."); 25031ba132491053bc86d419a7d51fc04af3299c076fredc } else { 25131ba132491053bc86d419a7d51fc04af3299c076fredc Log.i(TAG,"CURRENT_STATE=PENDING: Deferring request USER_TURN_OFF"); 25231ba132491053bc86d419a7d51fc04af3299c076fredc deferMessage(msg); 25331ba132491053bc86d419a7d51fc04af3299c076fredc } 254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 25531ba132491053bc86d419a7d51fc04af3299c076fredc case STARTED: { 25631ba132491053bc86d419a7d51fc04af3299c076fredc if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = STARTED, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); 25731ba132491053bc86d419a7d51fc04af3299c076fredc //Remove start timeout 25831ba132491053bc86d419a7d51fc04af3299c076fredc removeMessages(START_TIMEOUT); 25931ba132491053bc86d419a7d51fc04af3299c076fredc 26031ba132491053bc86d419a7d51fc04af3299c076fredc //Enable 2610eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu boolean ret = adapterService.enableNative(); 26231ba132491053bc86d419a7d51fc04af3299c076fredc if (!ret) { 26331ba132491053bc86d419a7d51fc04af3299c076fredc Log.e(TAG, "Error while turning Bluetooth On"); 2644852c5686229f1014e9851f4e9a3a19547581b45fredc notifyAdapterStateChange(BluetoothAdapter.STATE_OFF); 26531ba132491053bc86d419a7d51fc04af3299c076fredc transitionTo(mOffState); 26631ba132491053bc86d419a7d51fc04af3299c076fredc } else { 26731ba132491053bc86d419a7d51fc04af3299c076fredc sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY); 26831ba132491053bc86d419a7d51fc04af3299c076fredc } 26931ba132491053bc86d419a7d51fc04af3299c076fredc } 27031ba132491053bc86d419a7d51fc04af3299c076fredc break; 27131ba132491053bc86d419a7d51fc04af3299c076fredc 272ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case ENABLED_READY: 27331ba132491053bc86d419a7d51fc04af3299c076fredc if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = ENABLE_READY, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); 274ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh removeMessages(ENABLE_TIMEOUT); 2750eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu adapterProperties.onBluetoothReady(); 27631ba132491053bc86d419a7d51fc04af3299c076fredc mPendingCommandState.setTurningOn(false); 27731ba132491053bc86d419a7d51fc04af3299c076fredc transitionTo(mOnState); 2784852c5686229f1014e9851f4e9a3a19547581b45fredc notifyAdapterStateChange(BluetoothAdapter.STATE_ON); 27931ba132491053bc86d419a7d51fc04af3299c076fredc break; 28031ba132491053bc86d419a7d51fc04af3299c076fredc 28157a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie case SET_SCAN_MODE_TIMEOUT: 28257a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie Log.w(TAG,"Timeout will setting scan mode..Continuing with disable..."); 28357a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie //Fall through 28431ba132491053bc86d419a7d51fc04af3299c076fredc case BEGIN_DISABLE: { 285ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = BEGIN_DISABLE, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); 28657a3923845c46742ed4f03d49dbdbb6c774ccf90Matthew Xie removeMessages(SET_SCAN_MODE_TIMEOUT); 28731ba132491053bc86d419a7d51fc04af3299c076fredc sendMessageDelayed(DISABLE_TIMEOUT, DISABLE_TIMEOUT_DELAY); 2880eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu boolean ret = adapterService.disableNative(); 28931ba132491053bc86d419a7d51fc04af3299c076fredc if (!ret) { 29031ba132491053bc86d419a7d51fc04af3299c076fredc removeMessages(DISABLE_TIMEOUT); 29131ba132491053bc86d419a7d51fc04af3299c076fredc Log.e(TAG, "Error while turning Bluetooth Off"); 29231ba132491053bc86d419a7d51fc04af3299c076fredc //FIXME: what about post enable services 29331ba132491053bc86d419a7d51fc04af3299c076fredc mPendingCommandState.setTurningOff(false); 2944852c5686229f1014e9851f4e9a3a19547581b45fredc notifyAdapterStateChange(BluetoothAdapter.STATE_ON); 29531ba132491053bc86d419a7d51fc04af3299c076fredc } 29631ba132491053bc86d419a7d51fc04af3299c076fredc } 297ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 298ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case DISABLED: 29931ba132491053bc86d419a7d51fc04af3299c076fredc if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = DISABLED, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); 300ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao if (isTurningOn) { 301ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao removeMessages(ENABLE_TIMEOUT); 302ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao errorLog("Error enabling Bluetooth - hardware init failed"); 303ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao mPendingCommandState.setTurningOn(false); 304ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao transitionTo(mOffState); 3050eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu adapterService.stopProfileServices(); 306ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao notifyAdapterStateChange(BluetoothAdapter.STATE_OFF); 307ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao break; 308ad9fff218081d2f49471487d37387c764d69ed29YK Jeffrey Chao } 30931ba132491053bc86d419a7d51fc04af3299c076fredc removeMessages(DISABLE_TIMEOUT); 31031ba132491053bc86d419a7d51fc04af3299c076fredc sendMessageDelayed(STOP_TIMEOUT, STOP_TIMEOUT_DELAY); 3110eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu if (adapterService.stopProfileServices()) { 31231ba132491053bc86d419a7d51fc04af3299c076fredc Log.d(TAG,"Stopping profile services that were post enabled"); 31331ba132491053bc86d419a7d51fc04af3299c076fredc break; 31431ba132491053bc86d419a7d51fc04af3299c076fredc } 31574ae04c73312403e89db0f8e9bd9601d403b4783fredc //Fall through if no services or services already stopped 31631ba132491053bc86d419a7d51fc04af3299c076fredc case STOPPED: 31731ba132491053bc86d419a7d51fc04af3299c076fredc if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = STOPPED, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); 31831ba132491053bc86d419a7d51fc04af3299c076fredc removeMessages(STOP_TIMEOUT); 31931ba132491053bc86d419a7d51fc04af3299c076fredc setTurningOff(false); 32031ba132491053bc86d419a7d51fc04af3299c076fredc transitionTo(mOffState); 3214852c5686229f1014e9851f4e9a3a19547581b45fredc notifyAdapterStateChange(BluetoothAdapter.STATE_OFF); 32231ba132491053bc86d419a7d51fc04af3299c076fredc break; 32331ba132491053bc86d419a7d51fc04af3299c076fredc case START_TIMEOUT: 32431ba132491053bc86d419a7d51fc04af3299c076fredc if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = START_TIMEOUT, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); 32531ba132491053bc86d419a7d51fc04af3299c076fredc errorLog("Error enabling Bluetooth"); 32631ba132491053bc86d419a7d51fc04af3299c076fredc mPendingCommandState.setTurningOn(false); 327ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh transitionTo(mOffState); 3284852c5686229f1014e9851f4e9a3a19547581b45fredc notifyAdapterStateChange(BluetoothAdapter.STATE_OFF); 329ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 330ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh case ENABLE_TIMEOUT: 33131ba132491053bc86d419a7d51fc04af3299c076fredc if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = ENABLE_TIMEOUT, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); 332ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh errorLog("Error enabling Bluetooth"); 33331ba132491053bc86d419a7d51fc04af3299c076fredc mPendingCommandState.setTurningOn(false); 334ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh transitionTo(mOffState); 3354852c5686229f1014e9851f4e9a3a19547581b45fredc notifyAdapterStateChange(BluetoothAdapter.STATE_OFF); 33631ba132491053bc86d419a7d51fc04af3299c076fredc break; 33731ba132491053bc86d419a7d51fc04af3299c076fredc case STOP_TIMEOUT: 33831ba132491053bc86d419a7d51fc04af3299c076fredc if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = STOP_TIMEOUT, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); 33931ba132491053bc86d419a7d51fc04af3299c076fredc errorLog("Error stopping Bluetooth profiles"); 34031ba132491053bc86d419a7d51fc04af3299c076fredc mPendingCommandState.setTurningOff(false); 34131ba132491053bc86d419a7d51fc04af3299c076fredc transitionTo(mOffState); 34231ba132491053bc86d419a7d51fc04af3299c076fredc break; 34331ba132491053bc86d419a7d51fc04af3299c076fredc case DISABLE_TIMEOUT: 34431ba132491053bc86d419a7d51fc04af3299c076fredc if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = DISABLE_TIMEOUT, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff); 34531ba132491053bc86d419a7d51fc04af3299c076fredc errorLog("Error disabling Bluetooth"); 34631ba132491053bc86d419a7d51fc04af3299c076fredc mPendingCommandState.setTurningOff(false); 34731ba132491053bc86d419a7d51fc04af3299c076fredc transitionTo(mOnState); 348865b323bb1d0aa9581a9b6a2f5ed96fc0ee70b23Matthew Xie notifyAdapterStateChange(BluetoothAdapter.STATE_ON); 349ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh break; 350ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh default: 35131ba132491053bc86d419a7d51fc04af3299c076fredc if (DBG) Log.d(TAG,"ERROR: UNEXPECTED MESSAGE: CURRENT_STATE=PENDING, MESSAGE = " + msg.what ); 352ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return false; 353ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 354ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh return true; 355ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 356ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 357ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 358ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 3594852c5686229f1014e9851f4e9a3a19547581b45fredc private void notifyAdapterStateChange(int newState) { 3600eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu AdapterService adapterService = mAdapterService; 3610eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu AdapterProperties adapterProperties = mAdapterProperties; 3620eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu if ((adapterService == null) || (adapterProperties == null)) { 3630eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu Log.e(TAG,"notifyAdapterStateChange after cleanup:" + newState); 3640eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu return; 3650eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu } 3660eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu 3670eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu int oldState = adapterProperties.getState(); 3680eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu adapterProperties.setState(newState); 3694852c5686229f1014e9851f4e9a3a19547581b45fredc infoLog("Bluetooth adapter state changed: " + oldState + "-> " + newState); 3700eea1282dcb425c1ea9dc6aa08d323884a9a1655Zhihai Xu adapterService.updateAdapterState(oldState, newState); 371ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 372ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 373ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh void stateChangeCallback(int status) { 374ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (status == AbstractionLayer.BT_STATE_OFF) { 375ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh sendMessage(DISABLED); 376ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } else if (status == AbstractionLayer.BT_STATE_ON) { 377ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh // We should have got the property change for adapter and remote devices. 378ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh sendMessage(ENABLED_READY); 379ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } else { 380ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh errorLog("Incorrect status in stateChangeCallback"); 381ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 382ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 383ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 384ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private void infoLog(String msg) { 385ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh if (DBG) Log.i(TAG, msg); 386ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 387ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh 388ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh private void errorLog(String msg) { 389ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh Log.e(TAG, msg); 390ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh } 39115d36984a79d6e35c659edb0efdf929f0b526bd5Fred 392ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} 393