1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.bluetooth.btservice; 18 19 import android.bluetooth.BluetoothAdapter; 20 import android.os.Message; 21 import android.util.Log; 22 23 import com.android.bluetooth.R; 24 import com.android.bluetooth.telephony.BluetoothInCallService; 25 import com.android.bluetooth.statemachine.State; 26 import com.android.bluetooth.statemachine.StateMachine; 27 28 /** 29 * This state machine handles Bluetooth Adapter State. 30 * Stable States: 31 * {@link OffState}: Initial State 32 * {@link BleOnState} : Bluetooth Low Energy, Including GATT, is on 33 * {@link OnState} : Bluetooth is on (All supported profiles) 34 * 35 * Transition States: 36 * {@link TurningBleOnState} : OffState to BleOnState 37 * {@link TurningBleOffState} : BleOnState to OffState 38 * {@link TurningOnState} : BleOnState to OnState 39 * {@link TurningOffState} : OnState to BleOnState 40 * 41 * +------ Off <-----+ 42 * | | 43 * v | 44 * TurningBleOn TO---> TurningBleOff 45 * | ^ ^ 46 * | | | 47 * +-----> ----+ | 48 * BleOn | 49 * +------ <---+ O 50 * v | T 51 * TurningOn TO----> TurningOff 52 * | ^ 53 * | | 54 * +-----> On ------+ 55 * 56 */ 57 58 final class AdapterState extends StateMachine { 59 private static final boolean DBG = true; 60 private static final String TAG = AdapterState.class.getSimpleName(); 61 62 static final int USER_TURN_ON = 1; 63 static final int USER_TURN_OFF = 2; 64 static final int BLE_TURN_ON = 3; 65 static final int BLE_TURN_OFF = 4; 66 static final int BREDR_STARTED = 5; 67 static final int BREDR_STOPPED = 6; 68 static final int BLE_STARTED = 7; 69 static final int BLE_STOPPED = 8; 70 static final int BREDR_START_TIMEOUT = 9; 71 static final int BREDR_STOP_TIMEOUT = 10; 72 static final int BLE_STOP_TIMEOUT = 11; 73 static final int BLE_START_TIMEOUT = 12; 74 75 static final int BLE_START_TIMEOUT_DELAY = 4000; 76 static final int BLE_STOP_TIMEOUT_DELAY = 4000; 77 static final int BREDR_START_TIMEOUT_DELAY = 4000; 78 static final int BREDR_STOP_TIMEOUT_DELAY = 4000; 79 80 private AdapterService mAdapterService; 81 private TurningOnState mTurningOnState = new TurningOnState(); 82 private TurningBleOnState mTurningBleOnState = new TurningBleOnState(); 83 private TurningOffState mTurningOffState = new TurningOffState(); 84 private TurningBleOffState mTurningBleOffState = new TurningBleOffState(); 85 private OnState mOnState = new OnState(); 86 private OffState mOffState = new OffState(); 87 private BleOnState mBleOnState = new BleOnState(); 88 89 private int mPrevState = BluetoothAdapter.STATE_OFF; 90 AdapterState(AdapterService service)91 private AdapterState(AdapterService service) { 92 super(TAG); 93 addState(mOnState); 94 addState(mBleOnState); 95 addState(mOffState); 96 addState(mTurningOnState); 97 addState(mTurningOffState); 98 addState(mTurningBleOnState); 99 addState(mTurningBleOffState); 100 mAdapterService = service; 101 setInitialState(mOffState); 102 } 103 messageString(int message)104 private String messageString(int message) { 105 switch (message) { 106 case BLE_TURN_ON: return "BLE_TURN_ON"; 107 case USER_TURN_ON: return "USER_TURN_ON"; 108 case BREDR_STARTED: return "BREDR_STARTED"; 109 case BLE_STARTED: return "BLE_STARTED"; 110 case USER_TURN_OFF: return "USER_TURN_OFF"; 111 case BLE_TURN_OFF: return "BLE_TURN_OFF"; 112 case BLE_STOPPED: return "BLE_STOPPED"; 113 case BREDR_STOPPED: return "BREDR_STOPPED"; 114 case BLE_START_TIMEOUT: return "BLE_START_TIMEOUT"; 115 case BLE_STOP_TIMEOUT: return "BLE_STOP_TIMEOUT"; 116 case BREDR_START_TIMEOUT: return "BREDR_START_TIMEOUT"; 117 case BREDR_STOP_TIMEOUT: return "BREDR_STOP_TIMEOUT"; 118 default: return "Unknown message (" + message + ")"; 119 } 120 } 121 make(AdapterService service)122 public static AdapterState make(AdapterService service) { 123 Log.d(TAG, "make() - Creating AdapterState"); 124 AdapterState as = new AdapterState(service); 125 as.start(); 126 return as; 127 } 128 doQuit()129 public void doQuit() { 130 quitNow(); 131 } 132 cleanup()133 private void cleanup() { 134 if (mAdapterService != null) { 135 mAdapterService = null; 136 } 137 } 138 139 @Override onQuitting()140 protected void onQuitting() { 141 cleanup(); 142 } 143 144 @Override getLogRecString(Message msg)145 protected String getLogRecString(Message msg) { 146 return messageString(msg.what); 147 } 148 149 private abstract class BaseAdapterState extends State { 150 getStateValue()151 abstract int getStateValue(); 152 153 @Override enter()154 public void enter() { 155 int currState = getStateValue(); 156 infoLog("entered "); 157 mAdapterService.updateAdapterState(mPrevState, currState); 158 mPrevState = currState; 159 } 160 infoLog(String msg)161 void infoLog(String msg) { 162 if (DBG) { 163 Log.i(TAG, BluetoothAdapter.nameForState(getStateValue()) + " : " + msg); 164 } 165 } 166 errorLog(String msg)167 void errorLog(String msg) { 168 Log.e(TAG, BluetoothAdapter.nameForState(getStateValue()) + " : " + msg); 169 } 170 } 171 172 private class OffState extends BaseAdapterState { 173 174 @Override getStateValue()175 int getStateValue() { 176 return BluetoothAdapter.STATE_OFF; 177 } 178 179 @Override processMessage(Message msg)180 public boolean processMessage(Message msg) { 181 switch (msg.what) { 182 case BLE_TURN_ON: 183 transitionTo(mTurningBleOnState); 184 break; 185 186 default: 187 infoLog("Unhandled message - " + messageString(msg.what)); 188 return false; 189 } 190 return true; 191 } 192 } 193 194 private class BleOnState extends BaseAdapterState { 195 196 @Override getStateValue()197 int getStateValue() { 198 return BluetoothAdapter.STATE_BLE_ON; 199 } 200 201 @Override processMessage(Message msg)202 public boolean processMessage(Message msg) { 203 switch (msg.what) { 204 case USER_TURN_ON: 205 transitionTo(mTurningOnState); 206 break; 207 208 case BLE_TURN_OFF: 209 transitionTo(mTurningBleOffState); 210 break; 211 212 default: 213 infoLog("Unhandled message - " + messageString(msg.what)); 214 return false; 215 } 216 return true; 217 } 218 } 219 220 private class OnState extends BaseAdapterState { 221 222 @Override getStateValue()223 int getStateValue() { 224 return BluetoothAdapter.STATE_ON; 225 } 226 227 @Override enter()228 public void enter() { 229 super.enter(); 230 mAdapterService.enableBluetoothInCallService(true); 231 } 232 233 @Override exit()234 public void exit() { 235 BluetoothInCallService bluetoothInCallService = BluetoothInCallService.getInstance(); 236 if (bluetoothInCallService == null) { 237 mAdapterService.enableBluetoothInCallService(false); 238 } 239 super.exit(); 240 } 241 242 @Override processMessage(Message msg)243 public boolean processMessage(Message msg) { 244 switch (msg.what) { 245 case USER_TURN_OFF: 246 transitionTo(mTurningOffState); 247 break; 248 249 default: 250 infoLog("Unhandled message - " + messageString(msg.what)); 251 return false; 252 } 253 return true; 254 } 255 } 256 257 private class TurningBleOnState extends BaseAdapterState { 258 259 @Override getStateValue()260 int getStateValue() { 261 return BluetoothAdapter.STATE_BLE_TURNING_ON; 262 } 263 264 @Override enter()265 public void enter() { 266 super.enter(); 267 sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY); 268 mAdapterService.bringUpBle(); 269 } 270 271 @Override exit()272 public void exit() { 273 removeMessages(BLE_START_TIMEOUT); 274 super.exit(); 275 } 276 277 @Override processMessage(Message msg)278 public boolean processMessage(Message msg) { 279 switch (msg.what) { 280 case BLE_STARTED: 281 transitionTo(mBleOnState); 282 break; 283 284 case BLE_START_TIMEOUT: 285 errorLog(messageString(msg.what)); 286 transitionTo(mTurningBleOffState); 287 break; 288 289 default: 290 infoLog("Unhandled message - " + messageString(msg.what)); 291 return false; 292 } 293 return true; 294 } 295 } 296 297 private class TurningOnState extends BaseAdapterState { 298 299 @Override getStateValue()300 int getStateValue() { 301 return BluetoothAdapter.STATE_TURNING_ON; 302 } 303 304 @Override enter()305 public void enter() { 306 super.enter(); 307 sendMessageDelayed(BREDR_START_TIMEOUT, BREDR_START_TIMEOUT_DELAY); 308 mAdapterService.startProfileServices(); 309 } 310 311 @Override exit()312 public void exit() { 313 removeMessages(BREDR_START_TIMEOUT); 314 super.exit(); 315 } 316 317 @Override processMessage(Message msg)318 public boolean processMessage(Message msg) { 319 switch (msg.what) { 320 case BREDR_STARTED: 321 transitionTo(mOnState); 322 break; 323 324 case BREDR_START_TIMEOUT: 325 errorLog(messageString(msg.what)); 326 transitionTo(mTurningOffState); 327 break; 328 329 default: 330 infoLog("Unhandled message - " + messageString(msg.what)); 331 return false; 332 } 333 return true; 334 } 335 } 336 337 private class TurningOffState extends BaseAdapterState { 338 339 @Override getStateValue()340 int getStateValue() { 341 return BluetoothAdapter.STATE_TURNING_OFF; 342 } 343 344 @Override enter()345 public void enter() { 346 super.enter(); 347 sendMessageDelayed(BREDR_STOP_TIMEOUT, BREDR_STOP_TIMEOUT_DELAY); 348 mAdapterService.stopProfileServices(); 349 } 350 351 @Override exit()352 public void exit() { 353 removeMessages(BREDR_STOP_TIMEOUT); 354 super.exit(); 355 } 356 357 @Override processMessage(Message msg)358 public boolean processMessage(Message msg) { 359 switch (msg.what) { 360 case BREDR_STOPPED: 361 transitionTo(mBleOnState); 362 break; 363 364 case BREDR_STOP_TIMEOUT: 365 errorLog(messageString(msg.what)); 366 transitionTo(mTurningBleOffState); 367 break; 368 369 default: 370 infoLog("Unhandled message - " + messageString(msg.what)); 371 return false; 372 } 373 return true; 374 } 375 } 376 377 private class TurningBleOffState extends BaseAdapterState { 378 379 @Override getStateValue()380 int getStateValue() { 381 return BluetoothAdapter.STATE_BLE_TURNING_OFF; 382 } 383 384 @Override enter()385 public void enter() { 386 super.enter(); 387 mAdapterService.enableBluetoothInCallService(false); 388 sendMessageDelayed(BLE_STOP_TIMEOUT, BLE_STOP_TIMEOUT_DELAY); 389 mAdapterService.bringDownBle(); 390 } 391 392 @Override exit()393 public void exit() { 394 removeMessages(BLE_STOP_TIMEOUT); 395 super.exit(); 396 } 397 398 @Override processMessage(Message msg)399 public boolean processMessage(Message msg) { 400 switch (msg.what) { 401 case BLE_STOPPED: 402 transitionTo(mOffState); 403 break; 404 405 case BLE_STOP_TIMEOUT: 406 errorLog(messageString(msg.what)); 407 transitionTo(mOffState); 408 break; 409 410 default: 411 infoLog("Unhandled message - " + messageString(msg.what)); 412 return false; 413 } 414 return true; 415 } 416 } 417 } 418