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