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;
8d57031521f4687a573e82298843f6ac1906edddeWei Wangimport android.content.pm.PackageManager;
9435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wangimport android.net.wifi.IApInterface;
10435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wangimport android.net.wifi.IClientInterface;
11435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wangimport android.net.wifi.IInterfaceEventCallback;
1268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport android.net.wifi.IRttManager;
13435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wangimport android.net.wifi.IWificond;
14143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.net.wifi.RttManager;
1568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport android.net.wifi.RttManager.ResponderConfig;
16143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.net.wifi.WifiManager;
17d57031521f4687a573e82298843f6ac1906edddeWei Wangimport android.os.Binder;
1802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpandeimport android.os.Bundle;
19143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.Handler;
20143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.HandlerThread;
21435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wangimport android.os.IBinder;
22143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.Looper;
23143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.Message;
24143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.Messenger;
25143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.os.RemoteException;
26d57031521f4687a573e82298843f6ac1906edddeWei Wangimport android.util.ArrayMap;
27143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.util.Log;
28143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.util.Slog;
29143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
30d57031521f4687a573e82298843f6ac1906edddeWei Wangimport com.android.internal.annotations.GuardedBy;
31143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport com.android.internal.util.AsyncChannel;
32d57031521f4687a573e82298843f6ac1906edddeWei Wangimport com.android.internal.util.IState;
33143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport com.android.internal.util.Protocol;
34143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport com.android.internal.util.State;
3568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport com.android.internal.util.StateMachine;
36143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport com.android.server.SystemService;
37143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
38d57031521f4687a573e82298843f6ac1906edddeWei Wangimport java.io.FileDescriptor;
39d57031521f4687a573e82298843f6ac1906edddeWei Wangimport java.io.PrintWriter;
4068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport java.util.HashSet;
4102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpandeimport java.util.Iterator;
42143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport java.util.LinkedList;
43435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wangimport java.util.List;
44143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport java.util.Queue;
4568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport java.util.Set;
46143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
47eeefcd82f4c80048f7cf49bfc1972bdfce5ecf82Andreas Gampepublic final class RttService extends SystemService {
48143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
4902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande    public static final boolean DBG = true;
50435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang    private static final String WIFICOND_SERVICE_NAME = "wificond";
51143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
5268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    static class RttServiceImpl extends IRttManager.Stub {
53143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
54143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        @Override
55143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        public Messenger getMessenger() {
56143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            return new Messenger(mClientHandler);
57143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
58143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
59143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private class ClientHandler extends Handler {
60143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
61143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            ClientHandler(android.os.Looper looper) {
62143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                super(looper);
63143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
64143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
65143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            @Override
66143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            public void handleMessage(Message msg) {
67143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
6868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                if (DBG) {
6968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    Log.d(TAG, "ClientHandler got" + msg + " what = " + getDescription(msg.what));
7068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                }
71143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
72143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                switch (msg.what) {
73143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
74143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
75143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
76143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            Slog.e(TAG, "Send failed, client connection lost");
77143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        } else {
78143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
79143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        }
80143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        if (DBG) Slog.d(TAG, "closing client " + msg.replyTo);
81d57031521f4687a573e82298843f6ac1906edddeWei Wang                        synchronized (mLock) {
82d57031521f4687a573e82298843f6ac1906edddeWei Wang                            ClientInfo ci = mClients.remove(msg.replyTo);
83d57031521f4687a573e82298843f6ac1906edddeWei Wang                            if (ci != null) ci.cleanup();
84d57031521f4687a573e82298843f6ac1906edddeWei Wang                        }
85143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        return;
86143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
87143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        AsyncChannel ac = new AsyncChannel();
8868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        ac.connected(mContext, this, msg.replyTo);
89d57031521f4687a573e82298843f6ac1906edddeWei Wang                        ClientInfo client = new ClientInfo(ac, msg.sendingUid);
90d57031521f4687a573e82298843f6ac1906edddeWei Wang                        synchronized (mLock) {
91d57031521f4687a573e82298843f6ac1906edddeWei Wang                            mClients.put(msg.replyTo, client);
92d57031521f4687a573e82298843f6ac1906edddeWei Wang                        }
9368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
9468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                AsyncChannel.STATUS_SUCCESSFUL);
95143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        return;
96143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
97143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
98d57031521f4687a573e82298843f6ac1906edddeWei Wang                ClientInfo ci;
99d57031521f4687a573e82298843f6ac1906edddeWei Wang                synchronized (mLock) {
100d57031521f4687a573e82298843f6ac1906edddeWei Wang                    ci = mClients.get(msg.replyTo);
101d57031521f4687a573e82298843f6ac1906edddeWei Wang                }
102143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                if (ci == null) {
103143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    Slog.e(TAG, "Could not find client info for message " + msg.replyTo);
104143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    replyFailed(msg, RttManager.REASON_INVALID_LISTENER, "Could not find listener");
105143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    return;
106143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
107b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                if (!enforcePermissionCheck(msg)) {
108b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                    replyFailed(msg, RttManager.REASON_PERMISSION_DENIED,
109b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                            "Client doesn't have LOCATION_HARDWARE permission");
110b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                    return;
111b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                }
11268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                final int validCommands[] = {
113143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        RttManager.CMD_OP_START_RANGING,
11468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        RttManager.CMD_OP_STOP_RANGING,
11568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        RttManager.CMD_OP_ENABLE_RESPONDER,
11668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        RttManager.CMD_OP_DISABLE_RESPONDER,
117143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        };
118143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
11968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                for (int cmd : validCommands) {
120143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    if (cmd == msg.what) {
121143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        mStateMachine.sendMessage(Message.obtain(msg));
122143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        return;
123143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }
124143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
125143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
126143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                replyFailed(msg, RttManager.REASON_INVALID_REQUEST, "Invalid request");
127143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
12868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
12968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            private String getDescription(int what) {
13068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                switch(what) {
13168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    case RttManager.CMD_OP_ENABLE_RESPONDER:
13268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        return "CMD_OP_ENABLE_RESPONDER";
13368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    case RttManager.CMD_OP_DISABLE_RESPONDER:
13468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        return "CMD_OP_DISABLE_RESPONDER";
13568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    default:
13668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        return "CMD_UNKNOWN";
13768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                }
13868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
139143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
140143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
14118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        private final WifiNative mWifiNative;
14218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        private final Context mContext;
14368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        private final Looper mLooper;
144143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private RttStateMachine mStateMachine;
145143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private ClientHandler mClientHandler;
146435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang        private WifiInjector mWifiInjector;
147143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
148435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang        RttServiceImpl(Context context, Looper looper, WifiInjector wifiInjector) {
149143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            mContext = context;
150b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            mWifiNative = wifiInjector.getWifiNative();
15168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            mLooper = looper;
152435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            mWifiInjector = wifiInjector;
153143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
154143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
15518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        public void startService() {
15668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            mClientHandler = new ClientHandler(mLooper);
15768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            mStateMachine = new RttStateMachine(mLooper);
158143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            mContext.registerReceiver(
159143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    new BroadcastReceiver() {
160143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        @Override
161143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        public void onReceive(Context context, Intent intent) {
162143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            int state = intent.getIntExtra(
163143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                    WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_DISABLED);
164143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (DBG) Log.d(TAG, "SCAN_AVAILABLE : " + state);
165143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (state == WifiManager.WIFI_STATE_ENABLED) {
166143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                mStateMachine.sendMessage(CMD_DRIVER_LOADED);
167143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            } else if (state == WifiManager.WIFI_STATE_DISABLED) {
168143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                mStateMachine.sendMessage(CMD_DRIVER_UNLOADED);
169143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            }
170143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        }
171143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }, new IntentFilter(WifiManager.WIFI_SCAN_AVAILABLE));
172143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
173143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            mStateMachine.start();
174143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
175143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
176143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private class RttRequest {
177143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            Integer key;
178143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            ClientInfo ci;
17902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            RttManager.RttParams[] params;
180f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe
181f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe            @Override
182f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe            public String toString() {
183f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                String str = getClass().getName() + "@" + Integer.toHexString(hashCode());
184f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                if(this.key != null) {
185f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                    return str + " key: " + this.key;
186f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                } else {
187f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                    return str + " key: " + " , null";
188f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                }
189f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe            }
190143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
191143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
192143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private class ClientInfo {
193143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            private final AsyncChannel mChannel;
194d57031521f4687a573e82298843f6ac1906edddeWei Wang            private final int mUid;
195d57031521f4687a573e82298843f6ac1906edddeWei Wang
196d57031521f4687a573e82298843f6ac1906edddeWei Wang            ArrayMap<Integer, RttRequest> mRequests = new ArrayMap<>();
19768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            // Client keys of all outstanding responders.
19868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            Set<Integer> mResponderRequests = new HashSet<>();
199143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
200d57031521f4687a573e82298843f6ac1906edddeWei Wang            ClientInfo(AsyncChannel channel, int uid) {
201d57031521f4687a573e82298843f6ac1906edddeWei Wang                mChannel = channel;
202d57031521f4687a573e82298843f6ac1906edddeWei Wang                mUid = uid;
203143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
204143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
20568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            void addResponderRequest(int key) {
20668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                mResponderRequests.add(key);
20768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
20868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
20968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            void removeResponderRequest(int key) {
21068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                mResponderRequests.remove(key);
21168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
21268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
21302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            boolean addRttRequest(int key, RttManager.ParcelableRttParams parcelableParams) {
21402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                if (parcelableParams == null) {
21502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    return false;
21602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                }
21702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
21802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                RttManager.RttParams params[] = parcelableParams.mParams;
21902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
220143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                RttRequest request = new RttRequest();
221143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                request.key = key;
222143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                request.ci = this;
223143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                request.params = params;
22402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                mRequests.put(key, request);
225143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mRequestQueue.add(request);
22602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                return true;
227143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
228143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
229143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            void removeRttRequest(int key) {
230143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mRequests.remove(key);
231143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
232143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
23368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            void reportResponderEnableSucceed(int key, ResponderConfig config) {
23468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                mChannel.sendMessage(RttManager.CMD_OP_ENALBE_RESPONDER_SUCCEEDED, 0, key, config);
23568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
23668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
23787a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang            void reportResponderEnableFailed(int key, int reason) {
23887a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                mChannel.sendMessage(RttManager.CMD_OP_ENALBE_RESPONDER_FAILED, reason, key);
239d57031521f4687a573e82298843f6ac1906edddeWei Wang                removeResponderRequest(key);
24068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
24168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
242143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            void reportResult(RttRequest request, RttManager.RttResult[] results) {
24302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                RttManager.ParcelableRttResults parcelableResults =
24402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        new RttManager.ParcelableRttResults(results);
24502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
24602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                mChannel.sendMessage(RttManager.CMD_OP_SUCCEEDED,
24702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        0, request.key, parcelableResults);
248d57031521f4687a573e82298843f6ac1906edddeWei Wang                removeRttRequest(request.key);
249143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
250143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
251143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            void reportFailed(RttRequest request, int reason, String description) {
25202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                reportFailed(request.key, reason, description);
25302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            }
25402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
25502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            void reportFailed(int key, int reason, String description) {
25602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                Bundle bundle = new Bundle();
25702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                bundle.putString(RttManager.DESCRIPTION_KEY, description);
25802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                mChannel.sendMessage(RttManager.CMD_OP_FAILED, key, reason, bundle);
259d57031521f4687a573e82298843f6ac1906edddeWei Wang                removeRttRequest(key);
26002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            }
26102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
26202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            void reportAborted(int key) {
263f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                mChannel.sendMessage(RttManager.CMD_OP_ABORTED, 0, key);
264f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                //All Queued RTT request will be cleaned
265f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                cleanup();
266143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
267143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
268143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            void cleanup() {
269143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mRequests.clear();
270f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                mRequestQueue.clear();
271b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                // When client is lost, clean up responder requests and send disable responder
272b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                // message to RttStateMachine.
273b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                mResponderRequests.clear();
274b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                mStateMachine.sendMessage(RttManager.CMD_OP_DISABLE_RESPONDER);
275143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
276d57031521f4687a573e82298843f6ac1906edddeWei Wang
277d57031521f4687a573e82298843f6ac1906edddeWei Wang            @Override
278d57031521f4687a573e82298843f6ac1906edddeWei Wang            public String toString() {
279d57031521f4687a573e82298843f6ac1906edddeWei Wang                return "ClientInfo [uid=" + mUid + ", channel=" + mChannel + "]";
280d57031521f4687a573e82298843f6ac1906edddeWei Wang            }
281143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
282143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
283d57031521f4687a573e82298843f6ac1906edddeWei Wang        private Queue<RttRequest> mRequestQueue = new LinkedList<>();
284d57031521f4687a573e82298843f6ac1906edddeWei Wang
285d57031521f4687a573e82298843f6ac1906edddeWei Wang        @GuardedBy("mLock")
286d57031521f4687a573e82298843f6ac1906edddeWei Wang        private ArrayMap<Messenger, ClientInfo> mClients = new ArrayMap<>();
287d57031521f4687a573e82298843f6ac1906edddeWei Wang        // Lock for mClients.
288d57031521f4687a573e82298843f6ac1906edddeWei Wang        private final Object mLock = new Object();
289143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
29002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande        private static final int BASE = Protocol.BASE_WIFI_RTT_SERVICE;
291143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
292143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private static final int CMD_DRIVER_LOADED                       = BASE + 0;
293143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private static final int CMD_DRIVER_UNLOADED                     = BASE + 1;
294143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private static final int CMD_ISSUE_NEXT_REQUEST                  = BASE + 2;
295143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private static final int CMD_RTT_RESPONSE                        = BASE + 3;
296435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang        private static final int CMD_CLIENT_INTERFACE_READY              = BASE + 4;
297435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang        private static final int CMD_CLIENT_INTERFACE_DOWN               = BASE + 5;
298143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
29968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        // Maximum duration for responder role.
30068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        private static final int MAX_RESPONDER_DURATION_SECONDS = 60 * 10;
30168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
302435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang        private static class InterfaceEventHandler extends IInterfaceEventCallback.Stub {
303435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            InterfaceEventHandler(RttStateMachine rttStateMachine) {
304435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                mRttStateMachine = rttStateMachine;
305435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            }
306435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            @Override
307435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            public void OnClientTorndownEvent(IClientInterface networkInterface) {
308435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                mRttStateMachine.sendMessage(CMD_CLIENT_INTERFACE_DOWN, networkInterface);
309435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            }
310435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            @Override
311435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            public void OnClientInterfaceReady(IClientInterface networkInterface) {
312435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                mRttStateMachine.sendMessage(CMD_CLIENT_INTERFACE_READY, networkInterface);
313435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            }
314435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            @Override
315435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            public void OnApTorndownEvent(IApInterface networkInterface) { }
316435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            @Override
317435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            public void OnApInterfaceReady(IApInterface networkInterface) { }
318435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang
319435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            private RttStateMachine mRttStateMachine;
320435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang        }
321435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang
322143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        class RttStateMachine extends StateMachine {
323435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            private IWificond mWificond;
324435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            private InterfaceEventHandler mInterfaceEventHandler;
325435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang            private IClientInterface mClientInterface;
326143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
327143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            DefaultState mDefaultState = new DefaultState();
328143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            EnabledState mEnabledState = new EnabledState();
32968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            InitiatorEnabledState mInitiatorEnabledState = new InitiatorEnabledState();
33068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            ResponderEnabledState mResponderEnabledState = new ResponderEnabledState();
33168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            ResponderConfig mResponderConfig;
332143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
333143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttStateMachine(Looper looper) {
334143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                super("RttStateMachine", looper);
33502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
33668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                // CHECKSTYLE:OFF IndentationCheck
33702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                addState(mDefaultState);
33802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                addState(mEnabledState);
33968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    addState(mInitiatorEnabledState, mEnabledState);
34068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    addState(mResponderEnabledState, mEnabledState);
34168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                // CHECKSTYLE:ON IndentationCheck
34202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
34302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                setInitialState(mDefaultState);
344143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
345143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
346143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            class DefaultState extends State {
347143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                @Override
348143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                public boolean processMessage(Message msg) {
34902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    if (DBG) Log.d(TAG, "DefaultState got" + msg);
350143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    switch (msg.what) {
351143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_DRIVER_LOADED:
352143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            transitionTo(mEnabledState);
353143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
354143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_ISSUE_NEXT_REQUEST:
355143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            deferMessage(msg);
356143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
35702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_START_RANGING:
35802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            replyFailed(msg, RttManager.REASON_NOT_AVAILABLE, "Try later");
35902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            break;
36002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_STOP_RANGING:
36102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            return HANDLED;
36268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_ENABLE_RESPONDER:
363d57031521f4687a573e82298843f6ac1906edddeWei Wang
364d57031521f4687a573e82298843f6ac1906edddeWei Wang                            ClientInfo client;
365d57031521f4687a573e82298843f6ac1906edddeWei Wang                            synchronized (mLock) {
366d57031521f4687a573e82298843f6ac1906edddeWei Wang                                client = mClients.get(msg.replyTo);
367d57031521f4687a573e82298843f6ac1906edddeWei Wang                            }
36887a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                            if (client == null) {
36987a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                                Log.e(TAG, "client not connected yet!");
37087a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                                break;
37187a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                            }
37287a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                            int key = msg.arg2;
37387a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                            client.reportResponderEnableFailed(key,
37487a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                                    RttManager.REASON_NOT_AVAILABLE);
37568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            break;
37668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_DISABLE_RESPONDER:
37768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            return HANDLED;
378143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        default:
379143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            return NOT_HANDLED;
380143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }
381143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    return HANDLED;
382143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
383143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
384143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
385143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            class EnabledState extends State {
386143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                @Override
387435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                public void enter() {
388435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    // This allows us to tolerate wificond restarts.
389435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    // When wificond restarts WifiStateMachine is supposed to go
390435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    // back to initial state and restart.
391435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    // 1) RttService watches for WIFI_STATE_ENABLED broadcasts
392435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    // 2) WifiStateMachine sends these broadcasts in the SupplicantStarted state
393435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    // 3) Since WSM will only be in SupplicantStarted for as long as wificond is
394435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    // alive, we refresh our wificond handler here and we don't subscribe to
395435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    // wificond's death explicitly.
396435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    mWificond = mWifiInjector.makeWificond();
397435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    if (mWificond == null) {
398435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                        Log.w(TAG, "Failed to get wificond binder handler");
399435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                        transitionTo(mDefaultState);
400435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    }
401435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    mInterfaceEventHandler = new InterfaceEventHandler(mStateMachine);
402435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    try {
403435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                        mWificond.RegisterCallback(mInterfaceEventHandler);
404435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                        // Get the current client interface, assuming there is at most
405435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                        // one client interface for now.
406435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                        List<IBinder> interfaces = mWificond.GetClientInterfaces();
407435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                        if (interfaces.size() > 0) {
408435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                            mStateMachine.sendMessage(
409435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                                    CMD_CLIENT_INTERFACE_READY,
410435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                                    IClientInterface.Stub.asInterface(interfaces.get(0)));
411435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                        }
412435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    } catch (RemoteException e1) { }
413435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang
414435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                }
415435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                @Override
416435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                public void exit() {
417435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    try {
418435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                        mWificond.UnregisterCallback(mInterfaceEventHandler);
419435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    } catch (RemoteException e1) { }
420435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                    mInterfaceEventHandler = null;
421435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                }
422435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                @Override
423143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                public boolean processMessage(Message msg) {
42402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    if (DBG) Log.d(TAG, "EnabledState got" + msg);
425d57031521f4687a573e82298843f6ac1906edddeWei Wang                    ClientInfo ci;
426d57031521f4687a573e82298843f6ac1906edddeWei Wang                    synchronized (mLock) {
427d57031521f4687a573e82298843f6ac1906edddeWei Wang                        ci = mClients.get(msg.replyTo);
428d57031521f4687a573e82298843f6ac1906edddeWei Wang                    }
42902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
430143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    switch (msg.what) {
431143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_DRIVER_UNLOADED:
432143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            transitionTo(mDefaultState);
433143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
434143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_ISSUE_NEXT_REQUEST:
435143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            deferMessage(msg);
43668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            transitionTo(mInitiatorEnabledState);
437143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
43802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_START_RANGING: {
439b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                            RttManager.ParcelableRttParams params =
440b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                    (RttManager.ParcelableRttParams)msg.obj;
441202fdf96e1e0191be37a916d97116df35fe3cbfcWei Wang                            if (params == null || params.mParams == null
442202fdf96e1e0191be37a916d97116df35fe3cbfcWei Wang                                    || params.mParams.length == 0) {
443b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                replyFailed(msg,
444b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                        RttManager.REASON_INVALID_REQUEST, "No params");
445b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                            } else if (ci.addRttRequest(msg.arg2, params) == false) {
446b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                replyFailed(msg,
447b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                        RttManager.REASON_INVALID_REQUEST, "Unspecified");
448b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                            } else {
449b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                sendMessage(CMD_ISSUE_NEXT_REQUEST);
45002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            }
451b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                        }
45202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            break;
45302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_STOP_RANGING:
45402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            for (Iterator<RttRequest> it = mRequestQueue.iterator();
45502a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    it.hasNext(); ) {
45602a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                RttRequest request = it.next();
45702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                if (request.key == msg.arg2) {
45802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    if (DBG) Log.d(TAG, "Cancelling not-yet-scheduled RTT");
45902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    mRequestQueue.remove(request);
46002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    request.ci.reportAborted(request.key);
46102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    break;
46202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                }
46302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            }
46402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            break;
46568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_ENABLE_RESPONDER:
46668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            int key = msg.arg2;
46768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            mResponderConfig =
46868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                    mWifiNative.enableRttResponder(MAX_RESPONDER_DURATION_SECONDS);
46968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            if (DBG) Log.d(TAG, "mWifiNative.enableRttResponder called");
47068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
47168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            if (mResponderConfig != null) {
47268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                // TODO: remove once mac address is added when enabling responder.
47368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                mResponderConfig.macAddress = mWifiNative.getMacAddress();
47468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                ci.addResponderRequest(key);
47568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                ci.reportResponderEnableSucceed(key, mResponderConfig);
47668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                transitionTo(mResponderEnabledState);
47768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            } else {
47868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                Log.e(TAG, "enable responder failed");
47987a0e55e7d75e305e0fb50a0748d2002cd44c984Wei Wang                                ci.reportResponderEnableFailed(key, RttManager.REASON_UNSPECIFIED);
48068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            }
48168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            break;
48268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_DISABLE_RESPONDER:
483b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                            break;
484435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                        case CMD_CLIENT_INTERFACE_DOWN:
485435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                            if (mClientInterface == (IClientInterface) msg.obj) {
486435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                                mClientInterface = null;
487435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                            }
488435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                            break;
489435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                        case CMD_CLIENT_INTERFACE_READY:
490435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                            mClientInterface = (IClientInterface) msg.obj;
491435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                            break;
492143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        default:
493143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            return NOT_HANDLED;
494143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }
495143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    return HANDLED;
496143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
497143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
498143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
49968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            class InitiatorEnabledState extends State {
500143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                RttRequest mOutstandingRequest;
501143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                @Override
502143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                public boolean processMessage(Message msg) {
50302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                    if (DBG) Log.d(TAG, "RequestPendingState got" + msg);
504143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    switch (msg.what) {
505143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_DRIVER_UNLOADED:
506143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (mOutstandingRequest != null) {
50718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                                mWifiNative.cancelRtt(mOutstandingRequest.params);
508f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                if (DBG) Log.d(TAG, "abort key: " + mOutstandingRequest.key);
50902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                mOutstandingRequest.ci.reportAborted(mOutstandingRequest.key);
51002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                mOutstandingRequest = null;
511143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            }
512143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            transitionTo(mDefaultState);
513143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
514143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_ISSUE_NEXT_REQUEST:
515143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            if (mOutstandingRequest == null) {
516143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                mOutstandingRequest = issueNextRequest();
517143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                if (mOutstandingRequest == null) {
518143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                    transitionTo(mEnabledState);
519143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                }
520f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                if(mOutstandingRequest != null) {
521b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                    if (DBG) Log.d(TAG, "new mOutstandingRequest.key is: " +
522b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                            mOutstandingRequest.key);
523f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                } else {
524b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                    if (DBG) Log.d(TAG,
525b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                                            "CMD_ISSUE_NEXT_REQUEST: mOutstandingRequest =null ");
526f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                }
527143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            } else {
528143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                /* just wait; we'll issue next request after
529143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                 * current one is finished */
530f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                 if (DBG) Log.d(TAG, "Current mOutstandingRequest.key is: " +
531f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                         mOutstandingRequest.key);
532f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                 if (DBG) Log.d(TAG, "Ignoring CMD_ISSUE_NEXT_REQUEST");
533143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            }
534143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
535143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        case CMD_RTT_RESPONSE:
536f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                            if (DBG) Log.d(TAG, "Received an RTT response from: " + msg.arg2);
537143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            mOutstandingRequest.ci.reportResult(
538143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                                    mOutstandingRequest, (RttManager.RttResult[])msg.obj);
53902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            mOutstandingRequest = null;
540143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            sendMessage(CMD_ISSUE_NEXT_REQUEST);
541143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            break;
54202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                        case RttManager.CMD_OP_STOP_RANGING:
54302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            if (mOutstandingRequest != null
54402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                    && msg.arg2 == mOutstandingRequest.key) {
545f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                if (DBG) Log.d(TAG, "Cancelling ongoing RTT of: " + msg.arg2);
54618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                                mWifiNative.cancelRtt(mOutstandingRequest.params);
54702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                mOutstandingRequest.ci.reportAborted(mOutstandingRequest.key);
54802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                mOutstandingRequest = null;
54902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                sendMessage(CMD_ISSUE_NEXT_REQUEST);
55002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            } else {
55102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                /* Let EnabledState handle this */
55202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                                return NOT_HANDLED;
55302a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            }
55402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande                            break;
555143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                        default:
556143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                            return NOT_HANDLED;
557143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    }
558143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    return HANDLED;
559143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
560143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
56168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
56268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            // Check if there are still outstanding responder requests from any client.
56368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            private boolean hasOutstandingReponderRequests() {
564d57031521f4687a573e82298843f6ac1906edddeWei Wang                synchronized (mLock) {
565d57031521f4687a573e82298843f6ac1906edddeWei Wang                    for (ClientInfo client : mClients.values()) {
566d57031521f4687a573e82298843f6ac1906edddeWei Wang                        if (!client.mResponderRequests.isEmpty()) {
567d57031521f4687a573e82298843f6ac1906edddeWei Wang                            return true;
568d57031521f4687a573e82298843f6ac1906edddeWei Wang                        }
56968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    }
57068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                }
57168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                return false;
57268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
57368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang
57468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            /**
57568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang             * Representing an outstanding RTT responder state.
57668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang             */
57768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            class ResponderEnabledState extends State {
57868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                @Override
57968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                public boolean processMessage(Message msg) {
58068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    if (DBG) Log.d(TAG, "ResponderEnabledState got " + msg);
581d57031521f4687a573e82298843f6ac1906edddeWei Wang                    ClientInfo ci;
582d57031521f4687a573e82298843f6ac1906edddeWei Wang                    synchronized (mLock) {
583d57031521f4687a573e82298843f6ac1906edddeWei Wang                        ci = mClients.get(msg.replyTo);
584d57031521f4687a573e82298843f6ac1906edddeWei Wang                    }
58568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    int key = msg.arg2;
58668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    switch(msg.what) {
58768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_ENABLE_RESPONDER:
58868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            // Responder already enabled, simply return the responder config.
58968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            ci.addResponderRequest(key);
59068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            ci.reportResponderEnableSucceed(key, mResponderConfig);
59168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            return HANDLED;
59268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_DISABLE_RESPONDER:
593b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                            if (ci != null) {
594b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                                ci.removeResponderRequest(key);
595b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                            }
59668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            // Only disable responder when there are no outstanding clients.
59768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            if (!hasOutstandingReponderRequests()) {
59868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                if (!mWifiNative.disableRttResponder()) {
59968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                    Log.e(TAG, "disable responder failed");
60068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                }
60168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                if (DBG) Log.d(TAG, "mWifiNative.disableRttResponder called");
60268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                transitionTo(mEnabledState);
60368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            }
60468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            return HANDLED;
60568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_START_RANGING:
60668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        case RttManager.CMD_OP_STOP_RANGING:  // fall through
60768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            // Concurrent initiator and responder role is not supported.
60868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            replyFailed(msg,
60968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                    RttManager.REASON_INITIATOR_NOT_ALLOWED_WHEN_RESPONDER_ON,
61068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                                    "Initiator not allowed when responder is turned on");
61168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            return HANDLED;
61268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                        default:
61368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                            return NOT_HANDLED;
61468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                    }
61568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                }
61668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang            }
617d57031521f4687a573e82298843f6ac1906edddeWei Wang
618d57031521f4687a573e82298843f6ac1906edddeWei Wang            /**
619d57031521f4687a573e82298843f6ac1906edddeWei Wang             * Returns name of current state.
620d57031521f4687a573e82298843f6ac1906edddeWei Wang             */
621d57031521f4687a573e82298843f6ac1906edddeWei Wang            String currentState() {
622d57031521f4687a573e82298843f6ac1906edddeWei Wang                IState state = getCurrentState();
623d57031521f4687a573e82298843f6ac1906edddeWei Wang                return state == null ? "null" : state.getName();
624d57031521f4687a573e82298843f6ac1906edddeWei Wang            }
625143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
626143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
627143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void replySucceeded(Message msg, Object obj) {
628143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            if (msg.replyTo != null) {
629143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                Message reply = Message.obtain();
630143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                reply.what = RttManager.CMD_OP_SUCCEEDED;
631143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                reply.arg2 = msg.arg2;
632143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                reply.obj = obj;
633143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                try {
634143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    msg.replyTo.send(reply);
635143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                } catch (RemoteException e) {
636143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                    // There's not much we can do if reply can't be sent!
637143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
638143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            } else {
639143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                // locally generated message; doesn't need a reply!
640143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
641143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
642143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
643143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void replyFailed(Message msg, int reason, String description) {
644143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            Message reply = Message.obtain();
645143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            reply.what = RttManager.CMD_OP_FAILED;
646143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            reply.arg1 = reason;
647143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            reply.arg2 = msg.arg2;
64802a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
64902a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            Bundle bundle = new Bundle();
65002a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            bundle.putString(RttManager.DESCRIPTION_KEY, description);
65102a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            reply.obj = bundle;
65202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande
653143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            try {
654b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                if (msg.replyTo != null) {
655b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                    msg.replyTo.send(reply);
656b39039bb466eb4ab3e71da9daadeaed9d686d40fWei Wang                }
657143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            } catch (RemoteException e) {
658143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                // There's not much we can do if reply can't be sent!
659143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
660143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
661143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
662b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe        boolean enforcePermissionCheck(Message msg) {
663b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe            try {
664b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                mContext.enforcePermission(Manifest.permission.LOCATION_HARDWARE,
665b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                         -1, msg.sendingUid, "LocationRTT");
666b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe            } catch (SecurityException e) {
66768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang                Log.e(TAG, "UID: " + msg.sendingUid + " has no LOCATION_HARDWARE Permission");
668b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe                return false;
669b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe            }
670b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe            return true;
671b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe        }
672b11bfe8318f52585b7fc65cbbe8890aa562eb525xinhe
673d57031521f4687a573e82298843f6ac1906edddeWei Wang        @Override
674d57031521f4687a573e82298843f6ac1906edddeWei Wang        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
675d57031521f4687a573e82298843f6ac1906edddeWei Wang            if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
676d57031521f4687a573e82298843f6ac1906edddeWei Wang                    != PackageManager.PERMISSION_GRANTED) {
677d57031521f4687a573e82298843f6ac1906edddeWei Wang                pw.println("Permission Denial: can't dump RttService from from pid="
678d57031521f4687a573e82298843f6ac1906edddeWei Wang                        + Binder.getCallingPid()
679d57031521f4687a573e82298843f6ac1906edddeWei Wang                        + ", uid=" + Binder.getCallingUid()
680d57031521f4687a573e82298843f6ac1906edddeWei Wang                        + " without permission "
681d57031521f4687a573e82298843f6ac1906edddeWei Wang                        + android.Manifest.permission.DUMP);
682d57031521f4687a573e82298843f6ac1906edddeWei Wang                return;
683d57031521f4687a573e82298843f6ac1906edddeWei Wang            }
684d57031521f4687a573e82298843f6ac1906edddeWei Wang            pw.println("current state: " + mStateMachine.currentState());
685d57031521f4687a573e82298843f6ac1906edddeWei Wang            pw.println("clients:");
686d57031521f4687a573e82298843f6ac1906edddeWei Wang            synchronized (mLock) {
687d57031521f4687a573e82298843f6ac1906edddeWei Wang                for (ClientInfo client : mClients.values()) {
688d57031521f4687a573e82298843f6ac1906edddeWei Wang                    pw.println("  " + client);
689d57031521f4687a573e82298843f6ac1906edddeWei Wang                }
690d57031521f4687a573e82298843f6ac1906edddeWei Wang            }
691d57031521f4687a573e82298843f6ac1906edddeWei Wang        }
692d57031521f4687a573e82298843f6ac1906edddeWei Wang
693143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        private WifiNative.RttEventHandler mEventHandler = new WifiNative.RttEventHandler() {
694143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            @Override
695143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            public void onRttResults(RttManager.RttResult[] result) {
696143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                mStateMachine.sendMessage(CMD_RTT_RESPONSE, result);
697143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
698143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        };
699143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
700143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        RttRequest issueNextRequest() {
701143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttRequest request = null;
70202a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            while (mRequestQueue.isEmpty() == false) {
703143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                request = mRequestQueue.remove();
704f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                if(request !=  null) {
70518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills                    if (mWifiNative.requestRtt(request.params, mEventHandler)) {
706f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                        if (DBG) Log.d(TAG, "Issued next RTT request with key: " + request.key);
707f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                        return request;
708f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                    } else {
709f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                        Log.e(TAG, "Fail to issue key at native layer");
710f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                        request.ci.reportFailed(request,
711f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                                RttManager.REASON_UNSPECIFIED, "Failed to start");
712f95649f33db0a328cb4c0bb5e10c7075e6c828f8xinhe                    }
713143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande                }
71402a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            }
715143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
716143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            /* all requests exhausted */
71702a1f98f2cecb8ae2d466d6f9fab06b473f970ddVinit Deshpande            if (DBG) Log.d(TAG, "No more requests left");
718143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            return null;
719143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
72012cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe        @Override
72112cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe        public RttManager.RttCapabilities getRttCapabilities() {
72218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            return mWifiNative.getRttCapabilities();
72312cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe        }
724143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
725143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
726143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    private static final String TAG = "RttService";
727143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    RttServiceImpl mImpl;
72868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    private final HandlerThread mHandlerThread;
729143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
730143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public RttService(Context context) {
731143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        super(context);
73268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        mHandlerThread = new HandlerThread("WifiRttService");
73368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang        mHandlerThread.start();
734143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        Log.i(TAG, "Creating " + Context.WIFI_RTT_SERVICE);
735143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
736143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
737143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    @Override
738143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public void onStart() {
739435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang        mImpl = new RttServiceImpl(getContext(),
740435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                mHandlerThread.getLooper(), WifiInjector.getInstance());
741143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
742143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        Log.i(TAG, "Starting " + Context.WIFI_RTT_SERVICE);
743143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        publishBinderService(Context.WIFI_RTT_SERVICE, mImpl);
744143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
745143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
746143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    @Override
747143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public void onBootPhase(int phase) {
748143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
749143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            Log.i(TAG, "Registering " + Context.WIFI_RTT_SERVICE);
750143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            if (mImpl == null) {
751435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                mImpl = new RttServiceImpl(getContext(),
752435236f48f94a8373fa71251a3223e642f446e77Ningyuan Wang                        mHandlerThread.getLooper(),  WifiInjector.getInstance());
753143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            }
75418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills            mImpl.startService();
755143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        }
756143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
75712cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe
75812cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe
759143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande}
760