AdapterState.java revision 4852c5686229f1014e9851f4e9a3a19547581b45
1ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/*
2ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * Copyright (C) 2012 Google Inc.
3ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
4ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
5ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshpackage com.android.bluetooth.btservice;
6ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
7ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.bluetooth.BluetoothAdapter;
8ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Context;
9ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.content.Intent;
10ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.os.Message;
11ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport android.util.Log;
12ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
13ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.State;
14ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshimport com.android.internal.util.StateMachine;
15ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
16ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/**
17ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * This state machine handles Bluetooth Adapter State.
18ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * States:
19ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      {@link OnState} : Bluetooth is on at this state
20ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      {@link OffState}: Bluetooth is off at this state. This is the initial
21ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      state.
22ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh *      {@link PendingCommandState} : An enable / disable operation is pending.
23ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * TODO(BT): Add per process on state.
24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshfinal class AdapterState extends StateMachine {
27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private static final boolean DBG = true;
28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private static final String TAG = "BluetoothAdapterState";
29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    static final int USER_TURN_ON = 1;
3131ba132491053bc86d419a7d51fc04af3299c076fredc    static final int STARTED=2;
3231ba132491053bc86d419a7d51fc04af3299c076fredc    static final int ENABLED_READY = 3;
33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
3431ba132491053bc86d419a7d51fc04af3299c076fredc    static final int USER_TURN_OFF = 20;
3531ba132491053bc86d419a7d51fc04af3299c076fredc    static final int BEGIN_DISABLE = 21;
3631ba132491053bc86d419a7d51fc04af3299c076fredc    static final int ALL_DEVICES_DISCONNECTED = 22;
3774ae04c73312403e89db0f8e9bd9601d403b4783fredc
3831ba132491053bc86d419a7d51fc04af3299c076fredc    static final int DISABLED = 24;
3931ba132491053bc86d419a7d51fc04af3299c076fredc    static final int STOPPED=25;
40ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
4131ba132491053bc86d419a7d51fc04af3299c076fredc    static final int START_TIMEOUT = 100;
4231ba132491053bc86d419a7d51fc04af3299c076fredc    static final int ENABLE_TIMEOUT = 101;
4331ba132491053bc86d419a7d51fc04af3299c076fredc    static final int DISABLE_TIMEOUT = 103;
4431ba132491053bc86d419a7d51fc04af3299c076fredc    static final int STOP_TIMEOUT = 104;
4531ba132491053bc86d419a7d51fc04af3299c076fredc
4631ba132491053bc86d419a7d51fc04af3299c076fredc    static final int USER_TURN_OFF_DELAY_MS=500;
4731ba132491053bc86d419a7d51fc04af3299c076fredc
4831ba132491053bc86d419a7d51fc04af3299c076fredc    //TODO: tune me
4931ba132491053bc86d419a7d51fc04af3299c076fredc    private static final int ENABLE_TIMEOUT_DELAY = 8000;
5031ba132491053bc86d419a7d51fc04af3299c076fredc    private static final int DISABLE_TIMEOUT_DELAY = 8000;
5131ba132491053bc86d419a7d51fc04af3299c076fredc    private static final int START_TIMEOUT_DELAY = 5000;
5231ba132491053bc86d419a7d51fc04af3299c076fredc    private static final int STOP_TIMEOUT_DELAY = 5000;
5331ba132491053bc86d419a7d51fc04af3299c076fredc    private static final int PROPERTY_OP_DELAY =2000;
546654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private AdapterService mAdapterService;
556654f5c903de510a70f9e72cd5ad7837b615d93ffredc    private AdapterProperties mAdapterProperties;
56ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private PendingCommandState mPendingCommandState = new PendingCommandState();
57ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private OnState mOnState = new OnState();
58ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private OffState mOffState = new OffState();
59ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
6031ba132491053bc86d419a7d51fc04af3299c076fredc    public boolean isTurningOn() {
6131ba132491053bc86d419a7d51fc04af3299c076fredc        boolean isTurningOn=  mPendingCommandState.isTurningOn();
6274ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (DBG) Log.d(TAG,"isTurningOn()=" + isTurningOn);
6331ba132491053bc86d419a7d51fc04af3299c076fredc        return isTurningOn;
64b5cc776c9353a203cdde97e62b25f05d9633d14cfredc    }
6531ba132491053bc86d419a7d51fc04af3299c076fredc
6631ba132491053bc86d419a7d51fc04af3299c076fredc    public boolean isTurningOff() {
6731ba132491053bc86d419a7d51fc04af3299c076fredc        boolean isTurningOff= mPendingCommandState.isTurningOff();
6874ae04c73312403e89db0f8e9bd9601d403b4783fredc        if (DBG) Log.d(TAG,"isTurningOff()=" + isTurningOff);
6931ba132491053bc86d419a7d51fc04af3299c076fredc        return isTurningOff;
7031ba132491053bc86d419a7d51fc04af3299c076fredc    }
7131ba132491053bc86d419a7d51fc04af3299c076fredc
7274ae04c73312403e89db0f8e9bd9601d403b4783fredc    public AdapterState(AdapterService service,AdapterProperties adapterProperties) {
73ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        super("BluetoothAdapterState:");
74ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mOnState);
75ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mOffState);
76ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        addState(mPendingCommandState);
77ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterService = service;
78ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterProperties = adapterProperties;
796654f5c903de510a70f9e72cd5ad7837b615d93ffredc        setInitialState(mOffState);
806654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
816654f5c903de510a70f9e72cd5ad7837b615d93ffredc
826654f5c903de510a70f9e72cd5ad7837b615d93ffredc    public void cleanup() {
833fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan        if(mAdapterProperties != null)
843fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan            mAdapterProperties = null;
853fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan        if(mAdapterService != null)
863fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan            mAdapterService = null;
87ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
88ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
89ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class OffState extends State {
90ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
91ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
9231ba132491053bc86d419a7d51fc04af3299c076fredc            infoLog("Entering OffState");
93ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
94ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
95ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
96ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
97b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            if (msg.what == SM_QUIT_CMD) {
98b5cc776c9353a203cdde97e62b25f05d9633d14cfredc                Log.d(TAG, "Received quit request...");
99b5cc776c9353a203cdde97e62b25f05d9633d14cfredc                return false;
100b5cc776c9353a203cdde97e62b25f05d9633d14cfredc            }
10131ba132491053bc86d419a7d51fc04af3299c076fredc            int requestId = msg.arg1;
102b5cc776c9353a203cdde97e62b25f05d9633d14cfredc
103ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch(msg.what) {
104ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               case USER_TURN_ON:
10531ba132491053bc86d419a7d51fc04af3299c076fredc                   if (DBG) Log.d(TAG,"CURRENT_STATE=OFF, MESSAGE = USER_TURN_ON, requestId= " + msg.arg1);
1064852c5686229f1014e9851f4e9a3a19547581b45fredc                   notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_ON);
10731ba132491053bc86d419a7d51fc04af3299c076fredc                   mPendingCommandState.setTurningOn(true);
10831ba132491053bc86d419a7d51fc04af3299c076fredc                   transitionTo(mPendingCommandState);
10931ba132491053bc86d419a7d51fc04af3299c076fredc                   sendMessageDelayed(START_TIMEOUT, START_TIMEOUT_DELAY);
11031ba132491053bc86d419a7d51fc04af3299c076fredc                   mAdapterService.processStart();
111ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   break;
112ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               case USER_TURN_OFF:
11331ba132491053bc86d419a7d51fc04af3299c076fredc                   if (DBG) Log.d(TAG,"CURRENT_STATE=OFF, MESSAGE = USER_TURN_OFF, requestId= " + msg.arg1);
11431ba132491053bc86d419a7d51fc04af3299c076fredc                   //Handle case of service started and stopped without enable
11531ba132491053bc86d419a7d51fc04af3299c076fredc                   mAdapterService.startShutdown(requestId);
116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   break;
117ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               default:
11831ba132491053bc86d419a7d51fc04af3299c076fredc                   if (DBG) Log.d(TAG,"ERROR: UNEXPECTED MESSAGE: CURRENT_STATE=OFF, MESSAGE = " + msg.what );
119ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   return false;
120ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
121ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
122ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
123ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
124ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
125ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class OnState extends State {
126ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
127ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
128ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            infoLog("Entering On State");
129ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
130ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
131ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
132ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
133ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch(msg.what) {
134ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               case USER_TURN_OFF:
13531ba132491053bc86d419a7d51fc04af3299c076fredc                   if (DBG) Log.d(TAG,"CURRENT_STATE=ON, MESSAGE = USER_TURN_OFF, requestId= " + msg.arg1);
1364852c5686229f1014e9851f4e9a3a19547581b45fredc                   notifyAdapterStateChange(BluetoothAdapter.STATE_TURNING_OFF);
13731ba132491053bc86d419a7d51fc04af3299c076fredc                   mPendingCommandState.setTurningOff(true);
13831ba132491053bc86d419a7d51fc04af3299c076fredc                   mPendingCommandState.setOffRequestId(msg.arg1);
13931ba132491053bc86d419a7d51fc04af3299c076fredc                   transitionTo(mPendingCommandState);
14031ba132491053bc86d419a7d51fc04af3299c076fredc
141d570893c5ec3bc9fd1860aa0355c550d3a51f8ddKausik Sinnaswamy                   // Invoke onBluetoothDisable which shall trigger a
142d570893c5ec3bc9fd1860aa0355c550d3a51f8ddKausik Sinnaswamy                   // setScanMode to SCAN_MODE_NONE
14331ba132491053bc86d419a7d51fc04af3299c076fredc                   Message m = obtainMessage(BEGIN_DISABLE);
14431ba132491053bc86d419a7d51fc04af3299c076fredc                   m.arg1 = msg.arg1;
14531ba132491053bc86d419a7d51fc04af3299c076fredc                   sendMessageDelayed(m, PROPERTY_OP_DELAY);
146d570893c5ec3bc9fd1860aa0355c550d3a51f8ddKausik Sinnaswamy                   mAdapterProperties.onBluetoothDisable();
147ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   break;
14831ba132491053bc86d419a7d51fc04af3299c076fredc
149ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               case USER_TURN_ON:
15031ba132491053bc86d419a7d51fc04af3299c076fredc                   if (DBG) Log.d(TAG,"CURRENT_STATE=ON, MESSAGE = USER_TURN_ON, requestId= " + msg.arg1);
15131ba132491053bc86d419a7d51fc04af3299c076fredc                   Log.i(TAG,"Bluetooth already ON, ignoring USER_TURN_ON");
152ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   break;
153ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh               default:
15431ba132491053bc86d419a7d51fc04af3299c076fredc                   if (DBG) Log.d(TAG,"ERROR: UNEXPECTED MESSAGE: CURRENT_STATE=ON, MESSAGE = " + msg.what );
155ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                   return false;
156ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
157ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
158ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
159ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
160ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
161ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private class PendingCommandState extends State {
16231ba132491053bc86d419a7d51fc04af3299c076fredc        private boolean mIsTurningOn;
16331ba132491053bc86d419a7d51fc04af3299c076fredc        private boolean mIsTurningOff;
16431ba132491053bc86d419a7d51fc04af3299c076fredc
16531ba132491053bc86d419a7d51fc04af3299c076fredc        private int mRequestId;
16631ba132491053bc86d419a7d51fc04af3299c076fredc
167ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public void enter() {
16831ba132491053bc86d419a7d51fc04af3299c076fredc            infoLog("Entering PendingCommandState State: isTurningOn()=" + isTurningOn() + ", isTurningOff()=" + isTurningOff());
16931ba132491053bc86d419a7d51fc04af3299c076fredc        }
17031ba132491053bc86d419a7d51fc04af3299c076fredc
17131ba132491053bc86d419a7d51fc04af3299c076fredc        public void setTurningOn(boolean isTurningOn) {
17231ba132491053bc86d419a7d51fc04af3299c076fredc            mIsTurningOn = isTurningOn;
17331ba132491053bc86d419a7d51fc04af3299c076fredc        }
17431ba132491053bc86d419a7d51fc04af3299c076fredc
17531ba132491053bc86d419a7d51fc04af3299c076fredc        public boolean isTurningOn() {
17631ba132491053bc86d419a7d51fc04af3299c076fredc            return mIsTurningOn;
17731ba132491053bc86d419a7d51fc04af3299c076fredc        }
17831ba132491053bc86d419a7d51fc04af3299c076fredc
17931ba132491053bc86d419a7d51fc04af3299c076fredc        public void setTurningOff(boolean isTurningOff) {
18031ba132491053bc86d419a7d51fc04af3299c076fredc            mIsTurningOff = isTurningOff;
18131ba132491053bc86d419a7d51fc04af3299c076fredc        }
18231ba132491053bc86d419a7d51fc04af3299c076fredc
18331ba132491053bc86d419a7d51fc04af3299c076fredc        public boolean isTurningOff() {
18431ba132491053bc86d419a7d51fc04af3299c076fredc            return mIsTurningOff;
18531ba132491053bc86d419a7d51fc04af3299c076fredc        }
18631ba132491053bc86d419a7d51fc04af3299c076fredc
18731ba132491053bc86d419a7d51fc04af3299c076fredc        public void setOffRequestId(int requestId) {
18831ba132491053bc86d419a7d51fc04af3299c076fredc            mRequestId = requestId;
18931ba132491053bc86d419a7d51fc04af3299c076fredc        }
19031ba132491053bc86d419a7d51fc04af3299c076fredc
19131ba132491053bc86d419a7d51fc04af3299c076fredc        public int getOffRequestId() {
19231ba132491053bc86d419a7d51fc04af3299c076fredc            return mRequestId;
193ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
194ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
195ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        @Override
196ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        public boolean processMessage(Message msg) {
19731ba132491053bc86d419a7d51fc04af3299c076fredc            boolean isTurningOn= isTurningOn();
19831ba132491053bc86d419a7d51fc04af3299c076fredc            boolean isTurningOff = isTurningOff();
199ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            switch (msg.what) {
200ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case USER_TURN_ON:
20131ba132491053bc86d419a7d51fc04af3299c076fredc                    if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = USER_TURN_ON, requestId= " + msg.arg1
20231ba132491053bc86d419a7d51fc04af3299c076fredc                            + ", isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff);
20331ba132491053bc86d419a7d51fc04af3299c076fredc                    if (isTurningOn) {
20431ba132491053bc86d419a7d51fc04af3299c076fredc                        Log.i(TAG,"CURRENT_STATE=PENDING: Alreadying turning on bluetooth... Ignoring USER_TURN_ON...");
20531ba132491053bc86d419a7d51fc04af3299c076fredc                    } else {
20631ba132491053bc86d419a7d51fc04af3299c076fredc                        Log.i(TAG,"CURRENT_STATE=PENDING: Deferring request USER_TURN_ON");
20731ba132491053bc86d419a7d51fc04af3299c076fredc                        deferMessage(msg);
20831ba132491053bc86d419a7d51fc04af3299c076fredc                    }
20931ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
210ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case USER_TURN_OFF:
21131ba132491053bc86d419a7d51fc04af3299c076fredc                    if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = USER_TURN_ON, requestId= " + msg.arg1
21231ba132491053bc86d419a7d51fc04af3299c076fredc                            + ", isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff);
21331ba132491053bc86d419a7d51fc04af3299c076fredc                    if (isTurningOff) {
21431ba132491053bc86d419a7d51fc04af3299c076fredc                        Log.i(TAG,"CURRENT_STATE=PENDING: Alreadying turning off bluetooth... Ignoring USER_TURN_OFF...");
21531ba132491053bc86d419a7d51fc04af3299c076fredc                    } else {
21631ba132491053bc86d419a7d51fc04af3299c076fredc                        Log.i(TAG,"CURRENT_STATE=PENDING: Deferring request USER_TURN_OFF");
21731ba132491053bc86d419a7d51fc04af3299c076fredc                        deferMessage(msg);
21831ba132491053bc86d419a7d51fc04af3299c076fredc                    }
219ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
22031ba132491053bc86d419a7d51fc04af3299c076fredc                case STARTED:   {
22131ba132491053bc86d419a7d51fc04af3299c076fredc                    if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = STARTED, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff);
22231ba132491053bc86d419a7d51fc04af3299c076fredc                    //Remove start timeout
22331ba132491053bc86d419a7d51fc04af3299c076fredc                    removeMessages(START_TIMEOUT);
22431ba132491053bc86d419a7d51fc04af3299c076fredc
22531ba132491053bc86d419a7d51fc04af3299c076fredc                    //Enable
22631ba132491053bc86d419a7d51fc04af3299c076fredc                    boolean ret = mAdapterService.enableNative();
22731ba132491053bc86d419a7d51fc04af3299c076fredc                    if (!ret) {
22831ba132491053bc86d419a7d51fc04af3299c076fredc                        Log.e(TAG, "Error while turning Bluetooth On");
2294852c5686229f1014e9851f4e9a3a19547581b45fredc                        notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
23031ba132491053bc86d419a7d51fc04af3299c076fredc                        transitionTo(mOffState);
23131ba132491053bc86d419a7d51fc04af3299c076fredc                    } else {
23231ba132491053bc86d419a7d51fc04af3299c076fredc                        sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY);
23331ba132491053bc86d419a7d51fc04af3299c076fredc                    }
23431ba132491053bc86d419a7d51fc04af3299c076fredc                }
23531ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
23631ba132491053bc86d419a7d51fc04af3299c076fredc
237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case ENABLED_READY:
23831ba132491053bc86d419a7d51fc04af3299c076fredc                    if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = ENABLE_READY, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff);
239ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    removeMessages(ENABLE_TIMEOUT);
240b5cc776c9353a203cdde97e62b25f05d9633d14cfredc                    mAdapterProperties.onBluetoothReady();
24131ba132491053bc86d419a7d51fc04af3299c076fredc                    mPendingCommandState.setTurningOn(false);
24231ba132491053bc86d419a7d51fc04af3299c076fredc                    transitionTo(mOnState);
2434852c5686229f1014e9851f4e9a3a19547581b45fredc                    notifyAdapterStateChange(BluetoothAdapter.STATE_ON);
24431ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
24531ba132491053bc86d419a7d51fc04af3299c076fredc
24631ba132491053bc86d419a7d51fc04af3299c076fredc                case BEGIN_DISABLE: {
24731ba132491053bc86d419a7d51fc04af3299c076fredc                    if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = BEGIN_DISABLE" + isTurningOn + ", isTurningOff=" + isTurningOff);
24831ba132491053bc86d419a7d51fc04af3299c076fredc                    removeMessages(BEGIN_DISABLE); //Remove extra message we setup in USER_TURN_OFF
24931ba132491053bc86d419a7d51fc04af3299c076fredc                    //Log.d(TAG,"CURRENT_STATE=ON, MESSAGE = BEGIN_DISABLE_ON, requestId= " + msg.arg1);
25031ba132491053bc86d419a7d51fc04af3299c076fredc                    sendMessageDelayed(DISABLE_TIMEOUT, DISABLE_TIMEOUT_DELAY);
25131ba132491053bc86d419a7d51fc04af3299c076fredc                    boolean ret = mAdapterService.disableNative();
25231ba132491053bc86d419a7d51fc04af3299c076fredc                    if (!ret) {
25331ba132491053bc86d419a7d51fc04af3299c076fredc                        removeMessages(DISABLE_TIMEOUT);
25431ba132491053bc86d419a7d51fc04af3299c076fredc                        Log.e(TAG, "Error while turning Bluetooth Off");
25531ba132491053bc86d419a7d51fc04af3299c076fredc                        //FIXME: what about post enable services
25631ba132491053bc86d419a7d51fc04af3299c076fredc                        mPendingCommandState.setTurningOff(false);
25731ba132491053bc86d419a7d51fc04af3299c076fredc                        mPendingCommandState.setOffRequestId(-1);
2584852c5686229f1014e9851f4e9a3a19547581b45fredc                        notifyAdapterStateChange(BluetoothAdapter.STATE_ON);
25931ba132491053bc86d419a7d51fc04af3299c076fredc                    }
26031ba132491053bc86d419a7d51fc04af3299c076fredc                }
261ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
262ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case DISABLED:
26331ba132491053bc86d419a7d51fc04af3299c076fredc                    if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = DISABLED, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff);
26431ba132491053bc86d419a7d51fc04af3299c076fredc                    removeMessages(DISABLE_TIMEOUT);
26531ba132491053bc86d419a7d51fc04af3299c076fredc                    sendMessageDelayed(STOP_TIMEOUT, STOP_TIMEOUT_DELAY);
26631ba132491053bc86d419a7d51fc04af3299c076fredc                    if (mAdapterService.stopProfileServices()) {
26731ba132491053bc86d419a7d51fc04af3299c076fredc                        Log.d(TAG,"Stopping profile services that were post enabled");
26831ba132491053bc86d419a7d51fc04af3299c076fredc                        break;
26931ba132491053bc86d419a7d51fc04af3299c076fredc                    }
27074ae04c73312403e89db0f8e9bd9601d403b4783fredc                    //Fall through if no services or services already stopped
27131ba132491053bc86d419a7d51fc04af3299c076fredc                case STOPPED:
27231ba132491053bc86d419a7d51fc04af3299c076fredc                    if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = STOPPED, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff);
27331ba132491053bc86d419a7d51fc04af3299c076fredc                    removeMessages(STOP_TIMEOUT);
27431ba132491053bc86d419a7d51fc04af3299c076fredc                    setTurningOff(false);
27531ba132491053bc86d419a7d51fc04af3299c076fredc                    int requestId= getOffRequestId();
27631ba132491053bc86d419a7d51fc04af3299c076fredc                    setOffRequestId(-1);
27731ba132491053bc86d419a7d51fc04af3299c076fredc                    transitionTo(mOffState);
2784852c5686229f1014e9851f4e9a3a19547581b45fredc                    notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
27931ba132491053bc86d419a7d51fc04af3299c076fredc                    mAdapterService.startShutdown(requestId);
28031ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
28131ba132491053bc86d419a7d51fc04af3299c076fredc                case START_TIMEOUT:
28231ba132491053bc86d419a7d51fc04af3299c076fredc                    if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = START_TIMEOUT, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff);
28331ba132491053bc86d419a7d51fc04af3299c076fredc                    errorLog("Error enabling Bluetooth");
28431ba132491053bc86d419a7d51fc04af3299c076fredc                    mPendingCommandState.setTurningOn(false);
285ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    transitionTo(mOffState);
2864852c5686229f1014e9851f4e9a3a19547581b45fredc                    notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
287ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
288ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                case ENABLE_TIMEOUT:
28931ba132491053bc86d419a7d51fc04af3299c076fredc                    if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = ENABLE_TIMEOUT, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff);
290ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    errorLog("Error enabling Bluetooth");
29131ba132491053bc86d419a7d51fc04af3299c076fredc                    mPendingCommandState.setTurningOn(false);
292ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    transitionTo(mOffState);
2934852c5686229f1014e9851f4e9a3a19547581b45fredc                    notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
29431ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
29531ba132491053bc86d419a7d51fc04af3299c076fredc                case STOP_TIMEOUT:
29631ba132491053bc86d419a7d51fc04af3299c076fredc                    if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = STOP_TIMEOUT, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff);
29731ba132491053bc86d419a7d51fc04af3299c076fredc                    errorLog("Error stopping Bluetooth profiles");
29831ba132491053bc86d419a7d51fc04af3299c076fredc                    mPendingCommandState.setTurningOff(false);
29931ba132491053bc86d419a7d51fc04af3299c076fredc                    transitionTo(mOffState);
30031ba132491053bc86d419a7d51fc04af3299c076fredc                    break;
30131ba132491053bc86d419a7d51fc04af3299c076fredc                case DISABLE_TIMEOUT:
30231ba132491053bc86d419a7d51fc04af3299c076fredc                    if (DBG) Log.d(TAG,"CURRENT_STATE=PENDING, MESSAGE = DISABLE_TIMEOUT, isTurningOn=" + isTurningOn + ", isTurningOff=" + isTurningOff);
30331ba132491053bc86d419a7d51fc04af3299c076fredc                    errorLog("Error disabling Bluetooth");
30431ba132491053bc86d419a7d51fc04af3299c076fredc                    mPendingCommandState.setTurningOff(false);
30531ba132491053bc86d419a7d51fc04af3299c076fredc                    transitionTo(mOnState);
306ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    break;
307ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                default:
30831ba132491053bc86d419a7d51fc04af3299c076fredc                    if (DBG) Log.d(TAG,"ERROR: UNEXPECTED MESSAGE: CURRENT_STATE=PENDING, MESSAGE = " + msg.what );
309ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                    return false;
310ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
311ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return true;
312ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
313ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
314ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
315ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
3164852c5686229f1014e9851f4e9a3a19547581b45fredc    private void notifyAdapterStateChange(int newState) {
317ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        int oldState = mAdapterProperties.getState();
318ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        mAdapterProperties.setState(newState);
3194852c5686229f1014e9851f4e9a3a19547581b45fredc        infoLog("Bluetooth adapter state changed: " + oldState + "-> " + newState);
3204852c5686229f1014e9851f4e9a3a19547581b45fredc        mAdapterService.updateAdapterState(oldState, newState);
321ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
322ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
323ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    void stateChangeCallback(int status) {
324ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (status == AbstractionLayer.BT_STATE_OFF) {
325ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            sendMessage(DISABLED);
326ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        } else if (status == AbstractionLayer.BT_STATE_ON) {
327ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh            // We should have got the property change for adapter and remote devices.
328ff68148a7fb74947ea5e7a337161108363cbe9f5Jaikumar Ganesh            sendMessage(ENABLED_READY);
329ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        } else {
330ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            errorLog("Incorrect status in stateChangeCallback");
331ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
332ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
333ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
334ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void infoLog(String msg) {
335ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (DBG) Log.i(TAG, msg);
336ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
337ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
338ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    private void errorLog(String msg) {
339ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        Log.e(TAG, msg);
340ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
341ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
342