RttService.java revision 02a1f98f2cecb8ae2d466d6f9fab06b473f970dd
1143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandepackage com.android.server.wifi;
2143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
3143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.content.BroadcastReceiver;
4143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.content.Context;
5143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.content.Intent;
6143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.content.IntentFilter;
7143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.net.wifi.RttManager;
8143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.net.wifi.WifiManager;
902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpandeimport android.os.Bundle;
10143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.Handler;
11143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.HandlerThread;
12143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.Looper;
13143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.Message;
14143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.Messenger;
1502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpandeimport android.os.Parcel;
16143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.RemoteException;
17143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.util.Log;
18143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.net.wifi.IRttManager;
19143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.util.Slog;
20143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
21143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport com.android.internal.util.AsyncChannel;
22143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport com.android.internal.util.Protocol;
23143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport com.android.internal.util.StateMachine;
24143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport com.android.internal.util.State;
25143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport com.android.server.SystemService;
26143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
27143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport java.util.HashMap;
2802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpandeimport java.util.Iterator;
29143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport java.util.LinkedList;
30143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport java.util.Queue;
31143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
32143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeclass RttService extends SystemService {
33143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
3402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande    public static final boolean DBG = true;
35143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
36143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    class RttServiceImpl extends IRttManager.Stub {
37143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
38143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        @Override
39143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        public Messenger getMessenger() {
40143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            return new Messenger(mClientHandler);
41143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
42143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
43143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private class ClientHandler extends Handler {
44143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
45143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            ClientHandler(android.os.Looper looper) {
46143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                super(looper);
47143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
48143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
49143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            @Override
50143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            public void handleMessage(Message msg) {
51143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
52143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                if (DBG) Log.d(TAG, "ClientHandler got" + msg);
53143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
54143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                switch (msg.what) {
55143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
56143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
57143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
58143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            AsyncChannel c = (AsyncChannel) msg.obj;
59143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (DBG) Slog.d(TAG, "New client listening to asynchronous messages: " +
60143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                    msg.replyTo);
61143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            ClientInfo cInfo = new ClientInfo(c, msg.replyTo);
62143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            mClients.put(msg.replyTo, cInfo);
63143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        } else {
64143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
65143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        }
66143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        return;
67143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
68143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
69143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            Slog.e(TAG, "Send failed, client connection lost");
70143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        } else {
71143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
72143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        }
73143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        if (DBG) Slog.d(TAG, "closing client " + msg.replyTo);
74143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        ClientInfo ci = mClients.remove(msg.replyTo);
75143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        ci.cleanup();
76143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        return;
77143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
78143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        AsyncChannel ac = new AsyncChannel();
79143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        ac.connect(mContext, this, msg.replyTo);
80143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        return;
81143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
82143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
83143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                ClientInfo ci = mClients.get(msg.replyTo);
84143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                if (ci == null) {
85143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    Slog.e(TAG, "Could not find client info for message " + msg.replyTo);
86143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    replyFailed(msg, RttManager.REASON_INVALID_LISTENER, "Could not find listener");
87143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    return;
88143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
89143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
90143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                int validCommands[] = {
91143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        RttManager.CMD_OP_START_RANGING,
92143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        RttManager.CMD_OP_STOP_RANGING
93143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        };
94143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
95143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                for(int cmd : validCommands) {
96143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    if (cmd == msg.what) {
97143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        mStateMachine.sendMessage(Message.obtain(msg));
98143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        return;
99143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }
100143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
101143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
102143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                replyFailed(msg, RttManager.REASON_INVALID_REQUEST, "Invalid request");
103143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
104143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
105143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
106143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private Context mContext;
107143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private RttStateMachine mStateMachine;
108143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private ClientHandler mClientHandler;
109143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
110143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        RttServiceImpl() { }
111143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
112143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        RttServiceImpl(Context context) {
113143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            mContext = context;
114143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
115143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
116143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        public void startService(Context context) {
117143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            mContext = context;
118143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
119143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            HandlerThread thread = new HandlerThread("WifiRttService");
120143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            thread.start();
121143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
122143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            mClientHandler = new ClientHandler(thread.getLooper());
123143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            mStateMachine = new RttStateMachine(thread.getLooper());
124143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
125143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            mContext.registerReceiver(
126143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    new BroadcastReceiver() {
127143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        @Override
128143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        public void onReceive(Context context, Intent intent) {
129143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            int state = intent.getIntExtra(
130143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                    WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_DISABLED);
131143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (DBG) Log.d(TAG, "SCAN_AVAILABLE : " + state);
132143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (state == WifiManager.WIFI_STATE_ENABLED) {
133143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                mStateMachine.sendMessage(CMD_DRIVER_LOADED);
134143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            } else if (state == WifiManager.WIFI_STATE_DISABLED) {
135143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                mStateMachine.sendMessage(CMD_DRIVER_UNLOADED);
136143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            }
137143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        }
138143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }, new IntentFilter(WifiManager.WIFI_SCAN_AVAILABLE));
139143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
140143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            mStateMachine.start();
141143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
142143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
143143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private class RttRequest {
144143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            Integer key;
145143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            ClientInfo ci;
14602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            RttManager.RttParams[] params;
147143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
148143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
149143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private class ClientInfo {
150143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            private final AsyncChannel mChannel;
151143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            private final Messenger mMessenger;
15202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            HashMap<Integer, RttRequest> mRequests = new HashMap<Integer,
15302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    RttRequest>();
154143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
155143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            ClientInfo(AsyncChannel c, Messenger m) {
156143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mChannel = c;
157143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mMessenger = m;
158143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
159143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
16002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            boolean addRttRequest(int key, RttManager.ParcelableRttParams parcelableParams) {
16102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                if (parcelableParams == null) {
16202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    return false;
16302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                }
16402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
16502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                RttManager.RttParams params[] = parcelableParams.mParams;
16602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
167143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                RttRequest request = new RttRequest();
168143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                request.key = key;
169143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                request.ci = this;
170143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                request.params = params;
17102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                mRequests.put(key, request);
172143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mRequestQueue.add(request);
17302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                return true;
174143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
175143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
176143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            void removeRttRequest(int key) {
177143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mRequests.remove(key);
178143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
179143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
180143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            void reportResult(RttRequest request, RttManager.RttResult[] results) {
18102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                RttManager.ParcelableRttResults parcelableResults =
18202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        new RttManager.ParcelableRttResults(results);
18302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
18402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                mChannel.sendMessage(RttManager.CMD_OP_SUCCEEDED,
18502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        0, request.key, parcelableResults);
186143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mRequests.remove(request.key);
187143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
188143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
189143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            void reportFailed(RttRequest request, int reason, String description) {
19002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                reportFailed(request.key, reason, description);
19102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            }
19202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
19302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            void reportFailed(int key, int reason, String description) {
19402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                Bundle bundle = new Bundle();
19502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                bundle.putString(RttManager.DESCRIPTION_KEY, description);
19602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                mChannel.sendMessage(RttManager.CMD_OP_FAILED, key, reason, bundle);
19702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                mRequests.remove(key);
19802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            }
19902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
20002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            void reportAborted(int key) {
20102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                mChannel.sendMessage(RttManager.CMD_OP_ABORTED, key);
20202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                mRequests.remove(key);
203143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
204143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
205143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            void cleanup() {
206143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mRequests.clear();
207143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
208143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
209143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
210143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private Queue<RttRequest> mRequestQueue = new LinkedList<RttRequest>();
211143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private HashMap<Messenger, ClientInfo> mClients = new HashMap<Messenger, ClientInfo>(4);
212143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
21302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande        private static final int BASE = Protocol.BASE_WIFI_RTT_SERVICE;
214143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
215143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private static final int CMD_DRIVER_LOADED                       = BASE + 0;
216143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private static final int CMD_DRIVER_UNLOADED                     = BASE + 1;
217143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private static final int CMD_ISSUE_NEXT_REQUEST                  = BASE + 2;
218143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private static final int CMD_RTT_RESPONSE                        = BASE + 3;
219143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
220143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        class RttStateMachine extends StateMachine {
221143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
222143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            DefaultState mDefaultState = new DefaultState();
223143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            EnabledState mEnabledState = new EnabledState();
224143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RequestPendingState mRequestPendingState = new RequestPendingState();
225143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
226143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttStateMachine(Looper looper) {
227143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                super("RttStateMachine", looper);
22802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
22902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                addState(mDefaultState);
23002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                addState(mEnabledState);
23102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    addState(mRequestPendingState, mEnabledState);
23202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
23302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                setInitialState(mDefaultState);
234143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
235143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
236143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            class DefaultState extends State {
237143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                @Override
238143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                public boolean processMessage(Message msg) {
23902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    if (DBG) Log.d(TAG, "DefaultState got" + msg);
240143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    switch (msg.what) {
241143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_DRIVER_LOADED:
242143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            transitionTo(mEnabledState);
243143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
244143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_ISSUE_NEXT_REQUEST:
245143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            deferMessage(msg);
246143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
24702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_START_RANGING:
24802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            replyFailed(msg, RttManager.REASON_NOT_AVAILABLE, "Try later");
24902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            break;
25002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_STOP_RANGING:
25102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            return HANDLED;
252143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        default:
253143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            return NOT_HANDLED;
254143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }
255143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    return HANDLED;
256143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
257143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
258143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
259143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            class EnabledState extends State {
260143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                @Override
261143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                public boolean processMessage(Message msg) {
26202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    if (DBG) Log.d(TAG, "EnabledState got" + msg);
26302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    ClientInfo ci = mClients.get(msg.replyTo);
26402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
265143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    switch (msg.what) {
266143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_DRIVER_UNLOADED:
267143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            transitionTo(mDefaultState);
268143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
269143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_ISSUE_NEXT_REQUEST:
270143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            deferMessage(msg);
271143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            transitionTo(mRequestPendingState);
272143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
27302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_START_RANGING: {
27402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                RttManager.ParcelableRttParams params =
27502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                        (RttManager.ParcelableRttParams)msg.obj;
27602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                if (params == null) {
27702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    replyFailed(msg,
27802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                            RttManager.REASON_INVALID_REQUEST, "No params");
27902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                } else if (ci.addRttRequest(msg.arg2, params) == false) {
28002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    replyFailed(msg,
28102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                            RttManager.REASON_INVALID_REQUEST, "Unspecified");
28202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                } else {
28302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    sendMessage(CMD_ISSUE_NEXT_REQUEST);
28402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                }
28502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            }
28602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            break;
28702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_STOP_RANGING:
28802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            for (Iterator<RttRequest> it = mRequestQueue.iterator();
28902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    it.hasNext(); ) {
29002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                RttRequest request = it.next();
29102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                if (request.key == msg.arg2) {
29202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    if (DBG) Log.d(TAG, "Cancelling not-yet-scheduled RTT");
29302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    mRequestQueue.remove(request);
29402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    request.ci.reportAborted(request.key);
29502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    break;
29602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                }
29702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            }
29802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            break;
299143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        default:
300143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            return NOT_HANDLED;
301143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }
302143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    return HANDLED;
303143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
304143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
305143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
306143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            class RequestPendingState extends State {
307143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                RttRequest mOutstandingRequest;
308143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                @Override
309143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                public boolean processMessage(Message msg) {
31002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    if (DBG) Log.d(TAG, "RequestPendingState got" + msg);
311143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    switch (msg.what) {
312143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_DRIVER_UNLOADED:
313143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (mOutstandingRequest != null) {
31402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                WifiNative.cancelRtt(mOutstandingRequest.params);
31502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                mOutstandingRequest.ci.reportAborted(mOutstandingRequest.key);
31602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                mOutstandingRequest = null;
317143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            }
318143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            transitionTo(mDefaultState);
319143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
320143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_ISSUE_NEXT_REQUEST:
321143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (mOutstandingRequest == null) {
322143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                mOutstandingRequest = issueNextRequest();
323143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                if (mOutstandingRequest == null) {
324143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                    transitionTo(mEnabledState);
325143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                }
326143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            } else {
327143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                /* just wait; we'll issue next request after
328143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                 * current one is finished */
32902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                if (DBG) Log.d(TAG, "Ignoring CMD_ISSUE_NEXT_REQUEST");
330143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            }
331143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
332143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_RTT_RESPONSE:
33302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            if (DBG) Log.d(TAG, "Received an RTT response");
334143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            mOutstandingRequest.ci.reportResult(
335143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                    mOutstandingRequest, (RttManager.RttResult[])msg.obj);
33602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            mOutstandingRequest = null;
337143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            sendMessage(CMD_ISSUE_NEXT_REQUEST);
338143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
33902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_STOP_RANGING:
34002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            if (mOutstandingRequest != null
34102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    && msg.arg2 == mOutstandingRequest.key) {
34202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                if (DBG) Log.d(TAG, "Cancelling ongoing RTT");
34302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                WifiNative.cancelRtt(mOutstandingRequest.params);
34402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                mOutstandingRequest.ci.reportAborted(mOutstandingRequest.key);
34502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                mOutstandingRequest = null;
34602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                sendMessage(CMD_ISSUE_NEXT_REQUEST);
34702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            } else {
34802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                /* Let EnabledState handle this */
34902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                return NOT_HANDLED;
35002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            }
35102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            break;
352143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        default:
353143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            return NOT_HANDLED;
354143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }
355143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    return HANDLED;
356143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
357143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
358143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
359143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
360143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void replySucceeded(Message msg, Object obj) {
361143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            if (msg.replyTo != null) {
362143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                Message reply = Message.obtain();
363143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                reply.what = RttManager.CMD_OP_SUCCEEDED;
364143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                reply.arg2 = msg.arg2;
365143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                reply.obj = obj;
366143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                try {
367143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    msg.replyTo.send(reply);
368143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                } catch (RemoteException e) {
369143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    // There's not much we can do if reply can't be sent!
370143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
371143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            } else {
372143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                // locally generated message; doesn't need a reply!
373143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
374143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
375143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
376143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void replyFailed(Message msg, int reason, String description) {
377143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            Message reply = Message.obtain();
378143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            reply.what = RttManager.CMD_OP_FAILED;
379143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            reply.arg1 = reason;
380143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            reply.arg2 = msg.arg2;
38102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
38202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            Bundle bundle = new Bundle();
38302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            bundle.putString(RttManager.DESCRIPTION_KEY, description);
38402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            reply.obj = bundle;
38502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
386143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            try {
387143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                msg.replyTo.send(reply);
388143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            } catch (RemoteException e) {
389143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                // There's not much we can do if reply can't be sent!
390143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
391143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
392143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
393143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private WifiNative.RttEventHandler mEventHandler = new WifiNative.RttEventHandler() {
394143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            @Override
395143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            public void onRttResults(RttManager.RttResult[] result) {
396143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mStateMachine.sendMessage(CMD_RTT_RESPONSE, result);
397143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
398143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        };
399143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
400143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        RttRequest issueNextRequest() {
401143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttRequest request = null;
40202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            while (mRequestQueue.isEmpty() == false) {
403143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                request = mRequestQueue.remove();
40402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                if (WifiNative.requestRtt(request.params, mEventHandler)) {
40502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    if (DBG) Log.d(TAG, "Issued next RTT request");
406143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    return request;
407143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                } else {
408143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    request.ci.reportFailed(request,
409143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            RttManager.REASON_UNSPECIFIED, "Failed to start");
410143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
41102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            }
412143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
413143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            /* all requests exhausted */
41402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            if (DBG) Log.d(TAG, "No more requests left");
415143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            return null;
416143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
417143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
418143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
419143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    private static final String TAG = "RttService";
420143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    RttServiceImpl mImpl;
421143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
422143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public RttService(Context context) {
423143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        super(context);
424143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        Log.i(TAG, "Creating " + Context.WIFI_RTT_SERVICE);
425143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
426143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
427143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    @Override
428143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public void onStart() {
429143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        mImpl = new RttServiceImpl(getContext());
430143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
431143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        Log.i(TAG, "Starting " + Context.WIFI_RTT_SERVICE);
432143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        publishBinderService(Context.WIFI_RTT_SERVICE, mImpl);
433143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
434143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
435143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    @Override
436143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public void onBootPhase(int phase) {
437143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
438143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            Log.i(TAG, "Registering " + Context.WIFI_RTT_SERVICE);
439143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            if (mImpl == null) {
440143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mImpl = new RttServiceImpl(getContext());
441143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
442143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            mImpl.startService(getContext());
443143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
444143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
445143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande}
446