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