Home | History | Annotate | Download | only in btservice
      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.internal.util.State;
     24 import com.android.internal.util.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 
     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 
    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 
    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 
    127     public void doQuit() {
    128         quitNow();
    129     }
    130 
    131     private void cleanup() {
    132         if (mAdapterService != null) {
    133             mAdapterService = null;
    134         }
    135     }
    136 
    137     @Override
    138     protected void onQuitting() {
    139         cleanup();
    140     }
    141 
    142     @Override
    143     protected String getLogRecString(Message msg) {
    144         return messageString(msg.what);
    145     }
    146 
    147     private abstract class BaseAdapterState extends State {
    148 
    149         abstract int getStateValue();
    150 
    151         @Override
    152         public void enter() {
    153             int currState = getStateValue();
    154             infoLog("entered ");
    155             mAdapterService.updateAdapterState(mPrevState, currState);
    156             mPrevState = currState;
    157         }
    158 
    159         void infoLog(String msg) {
    160             if (DBG) {
    161                 Log.i(TAG, BluetoothAdapter.nameForState(getStateValue()) + " : " + msg);
    162             }
    163         }
    164 
    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
    173         int getStateValue() {
    174             return BluetoothAdapter.STATE_OFF;
    175         }
    176 
    177         @Override
    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
    195         int getStateValue() {
    196             return BluetoothAdapter.STATE_BLE_ON;
    197         }
    198 
    199         @Override
    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
    221         int getStateValue() {
    222             return BluetoothAdapter.STATE_ON;
    223         }
    224 
    225         @Override
    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
    243         int getStateValue() {
    244             return BluetoothAdapter.STATE_BLE_TURNING_ON;
    245         }
    246 
    247         @Override
    248         public void enter() {
    249             super.enter();
    250             sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
    251             mAdapterService.bringUpBle();
    252         }
    253 
    254         @Override
    255         public void exit() {
    256             removeMessages(BLE_START_TIMEOUT);
    257             super.exit();
    258         }
    259 
    260         @Override
    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
    283         int getStateValue() {
    284             return BluetoothAdapter.STATE_TURNING_ON;
    285         }
    286 
    287         @Override
    288         public void enter() {
    289             super.enter();
    290             sendMessageDelayed(BREDR_START_TIMEOUT, BREDR_START_TIMEOUT_DELAY);
    291             mAdapterService.startProfileServices();
    292         }
    293 
    294         @Override
    295         public void exit() {
    296             removeMessages(BREDR_START_TIMEOUT);
    297             super.exit();
    298         }
    299 
    300         @Override
    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
    323         int getStateValue() {
    324             return BluetoothAdapter.STATE_TURNING_OFF;
    325         }
    326 
    327         @Override
    328         public void enter() {
    329             super.enter();
    330             sendMessageDelayed(BREDR_STOP_TIMEOUT, BREDR_STOP_TIMEOUT_DELAY);
    331             mAdapterService.stopProfileServices();
    332         }
    333 
    334         @Override
    335         public void exit() {
    336             removeMessages(BREDR_STOP_TIMEOUT);
    337             super.exit();
    338         }
    339 
    340         @Override
    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
    363         int getStateValue() {
    364             return BluetoothAdapter.STATE_BLE_TURNING_OFF;
    365         }
    366 
    367         @Override
    368         public void enter() {
    369             super.enter();
    370             sendMessageDelayed(BLE_STOP_TIMEOUT, BLE_STOP_TIMEOUT_DELAY);
    371             mAdapterService.bringDownBle();
    372         }
    373 
    374         @Override
    375         public void exit() {
    376             removeMessages(BLE_STOP_TIMEOUT);
    377             super.exit();
    378         }
    379 
    380         @Override
    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