1143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandepackage com.android.server.wifi;
2143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport android.Manifest;
4143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.content.BroadcastReceiver;
5143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.content.Context;
6143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.content.Intent;
7143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.content.IntentFilter;
868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport android.net.wifi.IRttManager;
9143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.net.wifi.RttManager;
1068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport android.net.wifi.RttManager.ResponderConfig;
11143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.net.wifi.WifiManager;
1202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpandeimport android.os.Bundle;
13143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.Handler;
14143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.HandlerThread;
15143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.Looper;
16143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.Message;
17143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.Messenger;
18143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.RemoteException;
19143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.util.Log;
20143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.util.Slog;
21143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
22143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport com.android.internal.util.AsyncChannel;
23143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport com.android.internal.util.Protocol;
24143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport com.android.internal.util.State;
2568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport com.android.internal.util.StateMachine;
26143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport com.android.server.SystemService;
27143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
28143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport java.util.HashMap;
2968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport java.util.HashSet;
3002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpandeimport java.util.Iterator;
31143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport java.util.LinkedList;
32143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport java.util.Queue;
3368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport java.util.Set;
34143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
35eeefcd82f4c80048f7cf49bfc1972bdfce5ecf82Andreas Gampepublic final class RttService extends SystemService {
36143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
3702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande    public static final boolean DBG = true;
38143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
3968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    static class RttServiceImpl extends IRttManager.Stub {
40143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
41143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        @Override
42143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        public Messenger getMessenger() {
43143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            return new Messenger(mClientHandler);
44143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
45143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
46143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private class ClientHandler extends Handler {
47143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
48143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            ClientHandler(android.os.Looper looper) {
49143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                super(looper);
50143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
51143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
52143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            @Override
53143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            public void handleMessage(Message msg) {
54143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
5568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                if (DBG) {
5668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    Log.d(TAG, "ClientHandler got" + msg + " what = " + getDescription(msg.what));
5768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                }
58143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
59143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                switch (msg.what) {
60143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
61143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
62143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
63143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            Slog.e(TAG, "Send failed, client connection lost");
64143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        } else {
65143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
66143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        }
67143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        if (DBG) Slog.d(TAG, "closing client " + msg.replyTo);
68143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        ClientInfo ci = mClients.remove(msg.replyTo);
69f392c0185c2bea228f89fd42fa4551fa19797e7aVinit Deshpande                        if (ci != null) ci.cleanup();
70143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        return;
71143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
72143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        AsyncChannel ac = new AsyncChannel();
7368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        ac.connected(mContext, this, msg.replyTo);
7468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        ClientInfo client = new ClientInfo(ac, msg.replyTo);
7568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        mClients.put(msg.replyTo, client);
7668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
7768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                AsyncChannel.STATUS_SUCCESSFUL);
78143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        return;
79143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
80143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
81143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                ClientInfo ci = mClients.get(msg.replyTo);
82143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                if (ci == null) {
83143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    Slog.e(TAG, "Could not find client info for message " + msg.replyTo);
84143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    replyFailed(msg, RttManager.REASON_INVALID_LISTENER, "Could not find listener");
85143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    return;
86143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
87b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                if (!enforcePermissionCheck(msg)) {
88b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                    replyFailed(msg, RttManager.REASON_PERMISSION_DENIED,
89b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                            "Client doesn't have LOCATION_HARDWARE permission");
90b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                    return;
91b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                }
9268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                final int validCommands[] = {
93143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        RttManager.CMD_OP_START_RANGING,
9468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        RttManager.CMD_OP_STOP_RANGING,
9568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        RttManager.CMD_OP_ENABLE_RESPONDER,
9668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        RttManager.CMD_OP_DISABLE_RESPONDER,
97143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        };
98143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
9968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                for (int cmd : validCommands) {
100143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    if (cmd == msg.what) {
101143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        mStateMachine.sendMessage(Message.obtain(msg));
102143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        return;
103143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }
104143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
105143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
106143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                replyFailed(msg, RttManager.REASON_INVALID_REQUEST, "Invalid request");
107143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
10868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
10968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            private String getDescription(int what) {
11068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                switch(what) {
11168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    case RttManager.CMD_OP_ENABLE_RESPONDER:
11268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        return "CMD_OP_ENABLE_RESPONDER";
11368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    case RttManager.CMD_OP_DISABLE_RESPONDER:
11468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        return "CMD_OP_DISABLE_RESPONDER";
11568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    default:
11668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        return "CMD_UNKNOWN";
11768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                }
11868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
119143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
120143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
12118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        private final WifiNative mWifiNative;
12218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        private final Context mContext;
12368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        private final Looper mLooper;
124143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private RttStateMachine mStateMachine;
125143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private ClientHandler mClientHandler;
126143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
12768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        RttServiceImpl(Context context, Looper looper) {
128143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            mContext = context;
12918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            mWifiNative = WifiNative.getWlanNativeInterface();
13068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            mLooper = looper;
131143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
132143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
13318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        public void startService() {
13468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            mClientHandler = new ClientHandler(mLooper);
13568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            mStateMachine = new RttStateMachine(mLooper);
136143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
137143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            mContext.registerReceiver(
138143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    new BroadcastReceiver() {
139143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        @Override
140143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        public void onReceive(Context context, Intent intent) {
141143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            int state = intent.getIntExtra(
142143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                    WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_DISABLED);
143143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (DBG) Log.d(TAG, "SCAN_AVAILABLE : " + state);
144143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (state == WifiManager.WIFI_STATE_ENABLED) {
145143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                mStateMachine.sendMessage(CMD_DRIVER_LOADED);
146143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            } else if (state == WifiManager.WIFI_STATE_DISABLED) {
147143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                mStateMachine.sendMessage(CMD_DRIVER_UNLOADED);
148143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            }
149143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        }
150143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }, new IntentFilter(WifiManager.WIFI_SCAN_AVAILABLE));
151143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
152143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            mStateMachine.start();
153143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
154143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
155143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private class RttRequest {
156143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            Integer key;
157143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            ClientInfo ci;
15802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            RttManager.RttParams[] params;
159f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe
160f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe            @Override
161f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe            public String toString() {
162f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                String str = getClass().getName() + "@" + Integer.toHexString(hashCode());
163f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                if(this.key != null) {
164f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                    return str + " key: " + this.key;
165f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                } else {
166f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                    return str + " key: " + " , null";
167f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                }
168f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe            }
169143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
170143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
171143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private class ClientInfo {
172143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            private final AsyncChannel mChannel;
173143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            private final Messenger mMessenger;
17402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            HashMap<Integer, RttRequest> mRequests = new HashMap<Integer,
17502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    RttRequest>();
17668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            // Client keys of all outstanding responders.
17768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            Set<Integer> mResponderRequests = new HashSet<>();
178143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
179143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            ClientInfo(AsyncChannel c, Messenger m) {
180143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mChannel = c;
181143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mMessenger = m;
182143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
183143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
18468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            void addResponderRequest(int key) {
18568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                mResponderRequests.add(key);
18668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
18768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
18868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            void removeResponderRequest(int key) {
18968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                mResponderRequests.remove(key);
19068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
19168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
19202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            boolean addRttRequest(int key, RttManager.ParcelableRttParams parcelableParams) {
19302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                if (parcelableParams == null) {
19402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    return false;
19502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                }
19602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
19702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                RttManager.RttParams params[] = parcelableParams.mParams;
19802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
199143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                RttRequest request = new RttRequest();
200143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                request.key = key;
201143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                request.ci = this;
202143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                request.params = params;
20302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                mRequests.put(key, request);
204143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mRequestQueue.add(request);
20502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                return true;
206143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
207143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
208143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            void removeRttRequest(int key) {
209143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mRequests.remove(key);
210143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
211143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
21268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            void reportResponderEnableSucceed(int key, ResponderConfig config) {
21368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                mChannel.sendMessage(RttManager.CMD_OP_ENALBE_RESPONDER_SUCCEEDED, 0, key, config);
21468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
21568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
21687a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang            void reportResponderEnableFailed(int key, int reason) {
21787a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                mChannel.sendMessage(RttManager.CMD_OP_ENALBE_RESPONDER_FAILED, reason, key);
21868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                mResponderRequests.remove(key);
21968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
22068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
221143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            void reportResult(RttRequest request, RttManager.RttResult[] results) {
22202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                RttManager.ParcelableRttResults parcelableResults =
22302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        new RttManager.ParcelableRttResults(results);
22402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
22502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                mChannel.sendMessage(RttManager.CMD_OP_SUCCEEDED,
22602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        0, request.key, parcelableResults);
227143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mRequests.remove(request.key);
228143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
229143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
230143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            void reportFailed(RttRequest request, int reason, String description) {
23102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                reportFailed(request.key, reason, description);
23202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            }
23302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
23402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            void reportFailed(int key, int reason, String description) {
23502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                Bundle bundle = new Bundle();
23602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                bundle.putString(RttManager.DESCRIPTION_KEY, description);
23702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                mChannel.sendMessage(RttManager.CMD_OP_FAILED, key, reason, bundle);
23802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                mRequests.remove(key);
23902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            }
24002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
24102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            void reportAborted(int key) {
242f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                mChannel.sendMessage(RttManager.CMD_OP_ABORTED, 0, key);
243f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                //All Queued RTT request will be cleaned
244f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                cleanup();
245143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
246143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
247143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            void cleanup() {
248143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mRequests.clear();
249f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                mRequestQueue.clear();
250b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                // When client is lost, clean up responder requests and send disable responder
251b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                // message to RttStateMachine.
252b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                mResponderRequests.clear();
253b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                mStateMachine.sendMessage(RttManager.CMD_OP_DISABLE_RESPONDER);
254143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
255143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
256143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
257143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private Queue<RttRequest> mRequestQueue = new LinkedList<RttRequest>();
258143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private HashMap<Messenger, ClientInfo> mClients = new HashMap<Messenger, ClientInfo>(4);
259143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
26002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande        private static final int BASE = Protocol.BASE_WIFI_RTT_SERVICE;
261143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
262143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private static final int CMD_DRIVER_LOADED                       = BASE + 0;
263143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private static final int CMD_DRIVER_UNLOADED                     = BASE + 1;
264143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private static final int CMD_ISSUE_NEXT_REQUEST                  = BASE + 2;
265143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private static final int CMD_RTT_RESPONSE                        = BASE + 3;
266143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
26768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        // Maximum duration for responder role.
26868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        private static final int MAX_RESPONDER_DURATION_SECONDS = 60 * 10;
26968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
270143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        class RttStateMachine extends StateMachine {
271143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
272143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            DefaultState mDefaultState = new DefaultState();
273143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            EnabledState mEnabledState = new EnabledState();
27468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            InitiatorEnabledState mInitiatorEnabledState = new InitiatorEnabledState();
27568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            ResponderEnabledState mResponderEnabledState = new ResponderEnabledState();
27668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            ResponderConfig mResponderConfig;
277143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
278143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttStateMachine(Looper looper) {
279143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                super("RttStateMachine", looper);
28002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
28168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                // CHECKSTYLE:OFF IndentationCheck
28202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                addState(mDefaultState);
28302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                addState(mEnabledState);
28468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    addState(mInitiatorEnabledState, mEnabledState);
28568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    addState(mResponderEnabledState, mEnabledState);
28668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                // CHECKSTYLE:ON IndentationCheck
28702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
28802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                setInitialState(mDefaultState);
289143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
290143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
291143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            class DefaultState extends State {
292143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                @Override
293143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                public boolean processMessage(Message msg) {
29402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    if (DBG) Log.d(TAG, "DefaultState got" + msg);
295143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    switch (msg.what) {
296143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_DRIVER_LOADED:
297143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            transitionTo(mEnabledState);
298143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
299143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_ISSUE_NEXT_REQUEST:
300143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            deferMessage(msg);
301143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
30202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_START_RANGING:
30302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            replyFailed(msg, RttManager.REASON_NOT_AVAILABLE, "Try later");
30402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            break;
30502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_STOP_RANGING:
30602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            return HANDLED;
30768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_ENABLE_RESPONDER:
30887a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                            ClientInfo client = mClients.get(msg.replyTo);
30987a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                            if (client == null) {
31087a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                                Log.e(TAG, "client not connected yet!");
31187a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                                break;
31287a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                            }
31387a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                            int key = msg.arg2;
31487a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                            client.reportResponderEnableFailed(key,
31587a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                                    RttManager.REASON_NOT_AVAILABLE);
31668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            break;
31768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_DISABLE_RESPONDER:
31868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            return HANDLED;
319143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        default:
320143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            return NOT_HANDLED;
321143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }
322143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    return HANDLED;
323143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
324143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
325143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
326143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            class EnabledState extends State {
327143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                @Override
328143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                public boolean processMessage(Message msg) {
32902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    if (DBG) Log.d(TAG, "EnabledState got" + msg);
33002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    ClientInfo ci = mClients.get(msg.replyTo);
33102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
332143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    switch (msg.what) {
333143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_DRIVER_UNLOADED:
334143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            transitionTo(mDefaultState);
335143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
336143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_ISSUE_NEXT_REQUEST:
337143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            deferMessage(msg);
33868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            transitionTo(mInitiatorEnabledState);
339143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
34002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_START_RANGING: {
341b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                            RttManager.ParcelableRttParams params =
342b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                    (RttManager.ParcelableRttParams)msg.obj;
343202fdf96e1e0191be37a916d97116df35fe3cbfcWei Wang                            if (params == null || params.mParams == null
344202fdf96e1e0191be37a916d97116df35fe3cbfcWei Wang                                    || params.mParams.length == 0) {
345b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                replyFailed(msg,
346b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                        RttManager.REASON_INVALID_REQUEST, "No params");
347b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                            } else if (ci.addRttRequest(msg.arg2, params) == false) {
348b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                replyFailed(msg,
349b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                        RttManager.REASON_INVALID_REQUEST, "Unspecified");
350b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                            } else {
351b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                sendMessage(CMD_ISSUE_NEXT_REQUEST);
35202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            }
353b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                        }
35402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            break;
35502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_STOP_RANGING:
35602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            for (Iterator<RttRequest> it = mRequestQueue.iterator();
35702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    it.hasNext(); ) {
35802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                RttRequest request = it.next();
35902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                if (request.key == msg.arg2) {
36002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    if (DBG) Log.d(TAG, "Cancelling not-yet-scheduled RTT");
36102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    mRequestQueue.remove(request);
36202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    request.ci.reportAborted(request.key);
36302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    break;
36402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                }
36502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            }
36602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            break;
36768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_ENABLE_RESPONDER:
36868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            int key = msg.arg2;
36968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            mResponderConfig =
37068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                    mWifiNative.enableRttResponder(MAX_RESPONDER_DURATION_SECONDS);
37168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            if (DBG) Log.d(TAG, "mWifiNative.enableRttResponder called");
37268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
37368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            if (mResponderConfig != null) {
37468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                // TODO: remove once mac address is added when enabling responder.
37568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                mResponderConfig.macAddress = mWifiNative.getMacAddress();
37668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                ci.addResponderRequest(key);
37768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                ci.reportResponderEnableSucceed(key, mResponderConfig);
37868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                transitionTo(mResponderEnabledState);
37968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            } else {
38068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                Log.e(TAG, "enable responder failed");
38187a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                                ci.reportResponderEnableFailed(key, RttManager.REASON_UNSPECIFIED);
38268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            }
38368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            break;
38468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_DISABLE_RESPONDER:
385b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                            break;
386143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        default:
387143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            return NOT_HANDLED;
388143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }
389143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    return HANDLED;
390143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
391143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
392143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
39368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            class InitiatorEnabledState extends State {
394143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                RttRequest mOutstandingRequest;
395143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                @Override
396143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                public boolean processMessage(Message msg) {
39702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    if (DBG) Log.d(TAG, "RequestPendingState got" + msg);
398143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    switch (msg.what) {
399143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_DRIVER_UNLOADED:
400143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (mOutstandingRequest != null) {
40118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                                mWifiNative.cancelRtt(mOutstandingRequest.params);
402f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                if (DBG) Log.d(TAG, "abort key: " + mOutstandingRequest.key);
40302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                mOutstandingRequest.ci.reportAborted(mOutstandingRequest.key);
40402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                mOutstandingRequest = null;
405143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            }
406143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            transitionTo(mDefaultState);
407143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
408143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_ISSUE_NEXT_REQUEST:
409143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (mOutstandingRequest == null) {
410143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                mOutstandingRequest = issueNextRequest();
411143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                if (mOutstandingRequest == null) {
412143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                    transitionTo(mEnabledState);
413143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                }
414f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                if(mOutstandingRequest != null) {
415b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                    if (DBG) Log.d(TAG, "new mOutstandingRequest.key is: " +
416b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                            mOutstandingRequest.key);
417f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                } else {
418b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                    if (DBG) Log.d(TAG,
419b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                            "CMD_ISSUE_NEXT_REQUEST: mOutstandingRequest =null ");
420f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                }
421143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            } else {
422143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                /* just wait; we'll issue next request after
423143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                 * current one is finished */
424f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                 if (DBG) Log.d(TAG, "Current mOutstandingRequest.key is: " +
425f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                         mOutstandingRequest.key);
426f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                 if (DBG) Log.d(TAG, "Ignoring CMD_ISSUE_NEXT_REQUEST");
427143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            }
428143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
429143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_RTT_RESPONSE:
430f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                            if (DBG) Log.d(TAG, "Received an RTT response from: " + msg.arg2);
431143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            mOutstandingRequest.ci.reportResult(
432143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                    mOutstandingRequest, (RttManager.RttResult[])msg.obj);
43302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            mOutstandingRequest = null;
434143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            sendMessage(CMD_ISSUE_NEXT_REQUEST);
435143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
43602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_STOP_RANGING:
43702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            if (mOutstandingRequest != null
43802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    && msg.arg2 == mOutstandingRequest.key) {
439f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                if (DBG) Log.d(TAG, "Cancelling ongoing RTT of: " + msg.arg2);
44018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                                mWifiNative.cancelRtt(mOutstandingRequest.params);
44102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                mOutstandingRequest.ci.reportAborted(mOutstandingRequest.key);
44202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                mOutstandingRequest = null;
44302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                sendMessage(CMD_ISSUE_NEXT_REQUEST);
44402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            } else {
44502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                /* Let EnabledState handle this */
44602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                return NOT_HANDLED;
44702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            }
44802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            break;
449143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        default:
450143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            return NOT_HANDLED;
451143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }
452143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    return HANDLED;
453143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
454143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
45568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
45668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            // Check if there are still outstanding responder requests from any client.
45768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            private boolean hasOutstandingReponderRequests() {
45868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                for (ClientInfo client : mClients.values()) {
45968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    if (!client.mResponderRequests.isEmpty()) {
46068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        return true;
46168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    }
46268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                }
46368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                return false;
46468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
46568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
46668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            /**
46768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang             * Representing an outstanding RTT responder state.
46868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang             */
46968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            class ResponderEnabledState extends State {
47068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                @Override
47168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                public boolean processMessage(Message msg) {
47268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    if (DBG) Log.d(TAG, "ResponderEnabledState got " + msg);
47368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    ClientInfo ci = mClients.get(msg.replyTo);
47468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    int key = msg.arg2;
47568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    switch(msg.what) {
47668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_ENABLE_RESPONDER:
47768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            // Responder already enabled, simply return the responder config.
47868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            ci.addResponderRequest(key);
47968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            ci.reportResponderEnableSucceed(key, mResponderConfig);
48068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            return HANDLED;
48168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_DISABLE_RESPONDER:
482b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                            if (ci != null) {
483b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                                ci.removeResponderRequest(key);
484b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                            }
48568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            // Only disable responder when there are no outstanding clients.
48668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            if (!hasOutstandingReponderRequests()) {
48768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                if (!mWifiNative.disableRttResponder()) {
48868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                    Log.e(TAG, "disable responder failed");
48968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                }
49068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                if (DBG) Log.d(TAG, "mWifiNative.disableRttResponder called");
49168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                transitionTo(mEnabledState);
49268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            }
49368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            return HANDLED;
49468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_START_RANGING:
49568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_STOP_RANGING:  // fall through
49668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            // Concurrent initiator and responder role is not supported.
49768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            replyFailed(msg,
49868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                    RttManager.REASON_INITIATOR_NOT_ALLOWED_WHEN_RESPONDER_ON,
49968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                    "Initiator not allowed when responder is turned on");
50068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            return HANDLED;
50168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        default:
50268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            return NOT_HANDLED;
50368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    }
50468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                }
50568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
506143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
507143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
508143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void replySucceeded(Message msg, Object obj) {
509143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            if (msg.replyTo != null) {
510143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                Message reply = Message.obtain();
511143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                reply.what = RttManager.CMD_OP_SUCCEEDED;
512143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                reply.arg2 = msg.arg2;
513143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                reply.obj = obj;
514143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                try {
515143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    msg.replyTo.send(reply);
516143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                } catch (RemoteException e) {
517143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    // There's not much we can do if reply can't be sent!
518143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
519143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            } else {
520143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                // locally generated message; doesn't need a reply!
521143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
522143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
523143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
524143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void replyFailed(Message msg, int reason, String description) {
525143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            Message reply = Message.obtain();
526143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            reply.what = RttManager.CMD_OP_FAILED;
527143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            reply.arg1 = reason;
528143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            reply.arg2 = msg.arg2;
52902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
53002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            Bundle bundle = new Bundle();
53102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            bundle.putString(RttManager.DESCRIPTION_KEY, description);
53202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            reply.obj = bundle;
53302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
534143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            try {
535b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                if (msg.replyTo != null) {
536b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                    msg.replyTo.send(reply);
537b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                }
538143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            } catch (RemoteException e) {
539143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                // There's not much we can do if reply can't be sent!
540143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
541143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
542143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
543b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe        boolean enforcePermissionCheck(Message msg) {
544b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe            try {
545b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                mContext.enforcePermission(Manifest.permission.LOCATION_HARDWARE,
546b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                         -1, msg.sendingUid, "LocationRTT");
547b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe            } catch (SecurityException e) {
54868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                Log.e(TAG, "UID: " + msg.sendingUid + " has no LOCATION_HARDWARE Permission");
549b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                return false;
550b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe            }
551b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe            return true;
552b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe        }
553b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe
554143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private WifiNative.RttEventHandler mEventHandler = new WifiNative.RttEventHandler() {
555143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            @Override
556143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            public void onRttResults(RttManager.RttResult[] result) {
557143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mStateMachine.sendMessage(CMD_RTT_RESPONSE, result);
558143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
559143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        };
560143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
561143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        RttRequest issueNextRequest() {
562143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttRequest request = null;
56302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            while (mRequestQueue.isEmpty() == false) {
564143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                request = mRequestQueue.remove();
565f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                if(request !=  null) {
56618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    if (mWifiNative.requestRtt(request.params, mEventHandler)) {
567f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                        if (DBG) Log.d(TAG, "Issued next RTT request with key: " + request.key);
568f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                        return request;
569f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                    } else {
570f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                        Log.e(TAG, "Fail to issue key at native layer");
571f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                        request.ci.reportFailed(request,
572f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                RttManager.REASON_UNSPECIFIED, "Failed to start");
573f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                    }
574143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
57502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            }
576143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
577143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            /* all requests exhausted */
57802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            if (DBG) Log.d(TAG, "No more requests left");
579143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            return null;
580143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
58112cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe        @Override
58212cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe        public RttManager.RttCapabilities getRttCapabilities() {
58318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            return mWifiNative.getRttCapabilities();
58412cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe        }
585143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
586143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
587143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    private static final String TAG = "RttService";
588143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    RttServiceImpl mImpl;
58968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    private final HandlerThread mHandlerThread;
590143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
591143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public RttService(Context context) {
592143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        super(context);
59368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        mHandlerThread = new HandlerThread("WifiRttService");
59468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        mHandlerThread.start();
595143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        Log.i(TAG, "Creating " + Context.WIFI_RTT_SERVICE);
596143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
597143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
598143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    @Override
599143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public void onStart() {
60068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        mImpl = new RttServiceImpl(getContext(), mHandlerThread.getLooper());
601143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
602143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        Log.i(TAG, "Starting " + Context.WIFI_RTT_SERVICE);
603143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        publishBinderService(Context.WIFI_RTT_SERVICE, mImpl);
604143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
605143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
606143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    @Override
607143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public void onBootPhase(int phase) {
608143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
609143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            Log.i(TAG, "Registering " + Context.WIFI_RTT_SERVICE);
610143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            if (mImpl == null) {
61168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                mImpl = new RttServiceImpl(getContext(), mHandlerThread.getLooper());
612143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
61318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            mImpl.startService();
614143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
615143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
61612cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe
61712cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe
618143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande}
619