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