• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package android.net.wifi;
2 
3 import android.Manifest;
4 import android.annotation.NonNull;
5 import android.annotation.RequiresPermission;
6 import android.annotation.SuppressLint;
7 import android.annotation.SystemApi;
8 import android.annotation.SystemService;
9 import android.content.Context;
10 import android.os.Binder;
11 import android.os.Bundle;
12 import android.os.Handler;
13 import android.os.Looper;
14 import android.os.Message;
15 import android.os.Messenger;
16 import android.os.Parcel;
17 import android.os.Parcelable;
18 import android.os.RemoteException;
19 import android.util.Log;
20 import android.util.SparseArray;
21 
22 import com.android.internal.annotations.VisibleForTesting;
23 import com.android.internal.util.AsyncChannel;
24 import com.android.internal.util.Protocol;
25 
26 /** @hide */
27 @SystemApi
28 @SystemService(Context.WIFI_RTT_SERVICE)
29 public class RttManager {
30 
31     private static final boolean DBG = false;
32     private static final String TAG = "RttManager";
33 
34     /** @deprecated It is Not supported anymore. */
35     @Deprecated
36     public static final int RTT_TYPE_UNSPECIFIED        = 0;
37 
38     public static final int RTT_TYPE_ONE_SIDED          = 1;
39     public static final int RTT_TYPE_TWO_SIDED          = 2;
40 
41     /** @deprecated It is not supported anymore. */
42     @Deprecated
43     public static final int RTT_TYPE_11_V               = 2;
44 
45     /** @deprecated It is not supported anymore. */
46     @Deprecated
47     public static final int RTT_TYPE_11_MC              = 4;
48 
49     /** @deprecated It is not supported anymore. */
50     @Deprecated
51     public static final int RTT_PEER_TYPE_UNSPECIFIED    = 0;
52 
53     public static final int RTT_PEER_TYPE_AP             = 1;
54     public static final int RTT_PEER_TYPE_STA            = 2;       /* requires NAN */
55     public static final int RTT_PEER_P2P_GO              = 3;
56     public static final int RTT_PEER_P2P_CLIENT          = 4;
57     public static final int RTT_PEER_NAN                 = 5;
58 
59     /**
60      * @deprecated It is not supported anymore.
61      * Use {@link android.net.wifi.RttManager#RTT_BW_20_SUPPORT} API.
62      */
63     @Deprecated
64     public static final int RTT_CHANNEL_WIDTH_20      = 0;
65 
66     /**
67      * @deprecated It is not supported anymore.
68      * Use {@link android.net.wifi.RttManager#RTT_BW_40_SUPPORT} API.
69      */
70     @Deprecated
71     public static final int RTT_CHANNEL_WIDTH_40      = 1;
72 
73     /**
74      * @deprecated It is not supported anymore.
75      * Use {@link android.net.wifi.RttManager#RTT_BW_80_SUPPORT} API.
76      */
77     @Deprecated
78     public static final int RTT_CHANNEL_WIDTH_80      = 2;
79 
80     /**@deprecated It is not supported anymore.
81      * Use {@link android.net.wifi.RttManager#RTT_BW_160_SUPPORT} API.
82      */
83     @Deprecated
84     public static final int RTT_CHANNEL_WIDTH_160     = 3;
85 
86     /**@deprecated not supported anymore*/
87     @Deprecated
88     public static final int RTT_CHANNEL_WIDTH_80P80   = 4;
89 
90     /**@deprecated It is not supported anymore.
91      * Use {@link android.net.wifi.RttManager#RTT_BW_5_SUPPORT} API.
92      */
93     @Deprecated
94     public static final int RTT_CHANNEL_WIDTH_5       = 5;
95 
96     /**@deprecated It is not supported anymore.
97      * Use {@link android.net.wifi.RttManager#RTT_BW_10_SUPPORT} API.
98      */
99     @Deprecated
100     public static final int RTT_CHANNEL_WIDTH_10      = 6;
101 
102     /** @deprecated channel info must be specified. */
103     @Deprecated
104     public static final int RTT_CHANNEL_WIDTH_UNSPECIFIED = -1;
105 
106     public static final int RTT_STATUS_SUCCESS                  = 0;
107     /** General failure*/
108     public static final int RTT_STATUS_FAILURE                  = 1;
109     /** Destination does not respond to RTT request*/
110     public static final int RTT_STATUS_FAIL_NO_RSP              = 2;
111     /** RTT request is rejected by the destination. Double side RTT only*/
112     public static final int RTT_STATUS_FAIL_REJECTED            = 3;
113     /** */
114     public static final int RTT_STATUS_FAIL_NOT_SCHEDULED_YET   = 4;
115     /** Timing measurement timeout*/
116     public static final int RTT_STATUS_FAIL_TM_TIMEOUT          = 5;
117     /** Destination is on a different channel from the RTT Request*/
118     public static final int RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL  = 6;
119     /** This type of Ranging is not support by Hardware*/
120     public static final int RTT_STATUS_FAIL_NO_CAPABILITY       = 7;
121     /** Request abort fro uncertain reason*/
122     public static final int RTT_STATUS_ABORTED                  = 8;
123     /** The T1-T4 or TOD/TOA Timestamp is illegal*/
124     public static final int RTT_STATUS_FAIL_INVALID_TS          = 9;
125     /** 11mc protocol level failed, eg, unrecognized FTMR/FTM frame*/
126     public static final int RTT_STATUS_FAIL_PROTOCOL            = 10;
127     /** Request can not be scheduled by hardware*/
128     public static final int RTT_STATUS_FAIL_SCHEDULE            = 11;
129     /** destination is busy now, you can try after a specified time from destination*/
130     public static final int RTT_STATUS_FAIL_BUSY_TRY_LATER      = 12;
131     /** Bad Request argument*/
132     public static final int RTT_STATUS_INVALID_REQ              = 13;
133     /** Wifi is not enabled*/
134     public static final int RTT_STATUS_NO_WIFI                  = 14;
135     /** Responder overrides param info, cannot range with new params 2-side RTT only*/
136     public static final int RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE  = 15;
137 
138     public static final int REASON_UNSPECIFIED              = -1;
139     public static final int REASON_NOT_AVAILABLE            = -2;
140     public static final int REASON_INVALID_LISTENER         = -3;
141     public static final int REASON_INVALID_REQUEST          = -4;
142     /** Do not have required permission */
143     public static final int REASON_PERMISSION_DENIED        = -5;
144     /** Ranging failed because responder role is enabled in STA mode.*/
145     public static final int
146             REASON_INITIATOR_NOT_ALLOWED_WHEN_RESPONDER_ON  = -6;
147 
148     public static final String DESCRIPTION_KEY  = "android.net.wifi.RttManager.Description";
149 
150     /**
151      * RTT BW supported bit mask, used as RTT param bandWidth too
152      */
153     public static final int RTT_BW_5_SUPPORT   = 0x01;
154     public static final int RTT_BW_10_SUPPORT  = 0x02;
155     public static final int RTT_BW_20_SUPPORT  = 0x04;
156     public static final int RTT_BW_40_SUPPORT  = 0x08;
157     public static final int RTT_BW_80_SUPPORT  = 0x10;
158     public static final int RTT_BW_160_SUPPORT = 0x20;
159 
160     /**
161      * RTT Preamble Support bit mask
162      */
163     public static final int PREAMBLE_LEGACY  = 0x01;
164     public static final int PREAMBLE_HT      = 0x02;
165     public static final int PREAMBLE_VHT     = 0x04;
166 
167     /** @deprecated Use the new {@link android.net.wifi.RttManager.RttCapabilities} API */
168     @Deprecated
169     public class Capabilities {
170         public int supportedType;
171         public int supportedPeerType;
172     }
173 
174     /** @deprecated Use the new {@link android.net.wifi.RttManager#getRttCapabilities()} API.*/
175     @Deprecated
176     @SuppressLint("Doclava125")
getCapabilities()177     public Capabilities getCapabilities() {
178         return new Capabilities();
179     }
180 
181     /**
182      * This class describe the RTT capability of the Hardware
183      */
184     public static class RttCapabilities implements Parcelable {
185         /** @deprecated It is not supported*/
186         @Deprecated
187         public boolean supportedType;
188         /** @deprecated It is not supported*/
189         @Deprecated
190         public boolean supportedPeerType;
191         //1-sided rtt measurement is supported
192         public boolean oneSidedRttSupported;
193         //11mc 2-sided rtt measurement is supported
194         public boolean twoSided11McRttSupported;
195         //location configuration information supported
196         public boolean lciSupported;
197         //location civic records supported
198         public boolean lcrSupported;
199         //preamble supported, see bit mask definition above
200         public int preambleSupported;
201         //RTT bandwidth supported
202         public int bwSupported;
203         // Whether STA responder role is supported.
204         public boolean responderSupported;
205 
206         /** Whether the secure RTT protocol is supported. */
207         public boolean secureRttSupported;
208 
209         /** Draft 11mc version supported, including major and minor version. e.g, draft 4.3 is 43 */
210         public int mcVersion;
211 
212         @Override
toString()213         public String toString() {
214             StringBuffer sb = new StringBuffer();
215             sb.append("oneSidedRtt ").
216             append(oneSidedRttSupported ? "is Supported. " : "is not supported. ").
217             append("twoSided11McRtt ").
218             append(twoSided11McRttSupported ? "is Supported. " : "is not supported. ").
219             append("lci ").
220             append(lciSupported ? "is Supported. " : "is not supported. ").
221             append("lcr ").
222             append(lcrSupported ? "is Supported. " : "is not supported. ");
223 
224             if ((preambleSupported & PREAMBLE_LEGACY) != 0) {
225                 sb.append("Legacy ");
226             }
227 
228             if ((preambleSupported & PREAMBLE_HT) != 0) {
229                 sb.append("HT ");
230             }
231 
232             if ((preambleSupported & PREAMBLE_VHT) != 0) {
233                 sb.append("VHT ");
234             }
235 
236             sb.append("is supported. ");
237 
238             if ((bwSupported & RTT_BW_5_SUPPORT) != 0) {
239                 sb.append("5 MHz ");
240             }
241 
242             if ((bwSupported & RTT_BW_10_SUPPORT) != 0) {
243                 sb.append("10 MHz ");
244             }
245 
246             if ((bwSupported & RTT_BW_20_SUPPORT) != 0) {
247                 sb.append("20 MHz ");
248             }
249 
250             if ((bwSupported & RTT_BW_40_SUPPORT) != 0) {
251                 sb.append("40 MHz ");
252             }
253 
254             if ((bwSupported & RTT_BW_80_SUPPORT) != 0) {
255                 sb.append("80 MHz ");
256             }
257 
258             if ((bwSupported & RTT_BW_160_SUPPORT) != 0) {
259                 sb.append("160 MHz ");
260             }
261 
262             sb.append("is supported.");
263 
264             sb.append(" STA responder role is ")
265                     .append(responderSupported ? "supported" : "not supported");
266             sb.append(" Secure RTT protocol is ")
267                     .append(secureRttSupported ? "supported" : "not supported");
268             sb.append(" 11mc version is " + mcVersion);
269 
270             return sb.toString();
271         }
272         /** Implement the Parcelable interface {@hide} */
273         @Override
describeContents()274         public int describeContents() {
275             return 0;
276         }
277 
278         /** Implement the Parcelable interface {@hide} */
279         @Override
writeToParcel(Parcel dest, int flags)280         public void writeToParcel(Parcel dest, int flags) {
281             dest.writeInt(oneSidedRttSupported ? 1 : 0);
282             dest.writeInt(twoSided11McRttSupported ? 1 : 0);
283             dest.writeInt(lciSupported ? 1 : 0);
284             dest.writeInt(lcrSupported ? 1 : 0);
285             dest.writeInt(preambleSupported);
286             dest.writeInt(bwSupported);
287             dest.writeInt(responderSupported ? 1 : 0);
288             dest.writeInt(secureRttSupported ? 1 : 0);
289             dest.writeInt(mcVersion);
290         }
291 
292         /** Implement the Parcelable interface {@hide} */
293         public static final Creator<RttCapabilities> CREATOR =
294             new Creator<RttCapabilities>() {
295             @Override
296             public RttCapabilities createFromParcel(Parcel in) {
297                 RttCapabilities capabilities = new RttCapabilities();
298                 capabilities.oneSidedRttSupported = (in.readInt() == 1);
299                 capabilities.twoSided11McRttSupported = (in.readInt() == 1);
300                 capabilities.lciSupported = (in.readInt() == 1);
301                 capabilities.lcrSupported = (in.readInt() == 1);
302                 capabilities.preambleSupported = in.readInt();
303                 capabilities.bwSupported = in.readInt();
304                 capabilities.responderSupported = (in.readInt() == 1);
305                 capabilities.secureRttSupported = (in.readInt() == 1);
306                 capabilities.mcVersion = in.readInt();
307                 return capabilities;
308             }
309                 /** Implement the Parcelable interface {@hide} */
310                 @Override
311                 public RttCapabilities[] newArray(int size) {
312                     return new RttCapabilities[size];
313                 }
314              };
315     }
316 
317     @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
getRttCapabilities()318     public RttCapabilities getRttCapabilities() {
319         synchronized (mCapabilitiesLock) {
320             if (mRttCapabilities == null) {
321                 try {
322                     mRttCapabilities = mService.getRttCapabilities();
323                 } catch (RemoteException e) {
324                     throw e.rethrowFromSystemServer();
325                 }
326             }
327             return mRttCapabilities;
328         }
329     }
330 
331     /** specifies parameters for RTT request */
332     public static class RttParams {
333         /**
334          * type of destination device being ranged
335          * currently only support RTT_PEER_TYPE_AP
336          * Range:RTT_PEER_TYPE_xxxx Default value:RTT_PEER_TYPE_AP
337          */
338         public int deviceType;
339 
340         /**
341          * type of RTT measurement method. Need check scan result and RttCapabilities first
342          * Range: RTT_TYPE_ONE_SIDED or RTT_TYPE_TWO_SIDED
343          * Default value: RTT_TYPE_ONE_SIDED
344          */
345         public int requestType;
346 
347         /**
348          * Whether the secure RTT protocol needs to be used for ranging this peer device.
349          */
350         public boolean secure;
351 
352         /**
353          * mac address of the device being ranged
354          * Default value: null
355          */
356         public String bssid;
357 
358         /**
359          * The primary control channel over which the client is
360          * communicating with the AP.Same as ScanResult.frequency
361          * Default value: 0
362          */
363         public int frequency;
364 
365         /**
366          * channel width of the destination AP. Same as ScanResult.channelWidth
367          * Default value: 0
368          */
369         public int channelWidth;
370 
371         /**
372          * Not used if the AP bandwidth is 20 MHz
373          * If the AP use 40, 80 or 160 MHz, this is the center frequency
374          * if the AP use 80 + 80 MHz, this is the center frequency of the first segment
375          * same as ScanResult.centerFreq0
376          * Default value: 0
377          */
378          public int centerFreq0;
379 
380          /**
381           * Only used if the AP bandwidth is 80 + 80 MHz
382           * if the AP use 80 + 80 MHz, this is the center frequency of the second segment
383           * same as ScanResult.centerFreq1
384           * Default value: 0
385           */
386           public int centerFreq1;
387 
388         /**
389          * number of samples to be taken
390          * @deprecated Use the new {@link android.net.wifi.RttManager.RttParams#numSamplesPerBurst}
391          */
392         @Deprecated
393         public int num_samples;
394 
395         /**
396          * number of retries if a sample fails
397          * @deprecated
398          * Use {@link android.net.wifi.RttManager.RttParams#numRetriesPerMeasurementFrame} API.
399          */
400         @Deprecated
401         public int num_retries;
402 
403         /** Number of burst in exp , 2^x. 0 means single shot measurement, range 0-15
404          * Currently only single shot is supported
405          * Default value: 0
406          */
407         public int numberBurst;
408 
409         /**
410          * valid only if numberBurst > 1, interval between burst(100ms).
411          * Range : 0-31, 0--means no specific
412          * Default value: 0
413          */
414         public int interval;
415 
416         /**
417          * number of samples to be taken in one burst
418          * Range: 1-31
419          * Default value: 8
420          */
421         public int numSamplesPerBurst;
422 
423         /** number of retries for each measurement frame if a sample fails
424          *  Only used by single side RTT,
425          *  Range 0 - 3 Default value: 0
426          */
427         public int numRetriesPerMeasurementFrame;
428 
429         /**
430          * number of retries for FTMR frame (control frame) if it fails.
431          * Only used by 80211MC double side RTT
432          * Range: 0-3  Default Value : 0
433          */
434         public int numRetriesPerFTMR;
435 
436         /**
437          * Request LCI information, only available when choose double side RTT measurement
438          * need check RttCapabilties first.
439          * Default value: false
440          * */
441         public boolean LCIRequest;
442 
443         /**
444          * Request LCR information, only available when choose double side RTT measurement
445          * need check RttCapabilties first.
446          * Default value: false
447          * */
448         public boolean LCRRequest;
449 
450         /**
451          * Timeout for each burst, (250 * 2^x) us,
452          * Range 1-11 and 15. 15 means no control Default value: 15
453          * */
454         public int burstTimeout;
455 
456         /** preamble used for RTT measurement
457          *  Range: PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT
458          *  Default value: PREAMBLE_HT
459          */
460         public int preamble;
461 
462         /** bandWidth used for RTT measurement.User need verify the highest BW the destination
463          * support (from scan result etc) before set this value. Wider channels result usually give
464          * better accuracy. However, the frame loss can increase too.
465          * should be one of RTT_BW_5_SUPPORT to RTT_BW_160_SUPPORT. However, need check
466          * RttCapabilities firstto verify HW support this bandwidth.
467          * Default value:RTT_BW_20_SUPPORT
468          */
469         public int bandwidth;
470 
RttParams()471         public RttParams() {
472             //provide initial value for RttParams
473             deviceType = RTT_PEER_TYPE_AP;
474             requestType = RTT_TYPE_ONE_SIDED;
475             numberBurst = 0;
476             numSamplesPerBurst = 8;
477             numRetriesPerMeasurementFrame  = 0;
478             numRetriesPerFTMR = 0;
479             burstTimeout = 15;
480             preamble = PREAMBLE_HT;
481             bandwidth = RTT_BW_20_SUPPORT;
482         }
483 
484         /**
485          * {@hide}
486          */
toString()487         public String toString() {
488             StringBuilder sb = new StringBuilder();
489             sb.append("deviceType=" + deviceType);
490             sb.append(", requestType=" + requestType);
491             sb.append(", secure=" + secure);
492             sb.append(", bssid=" + bssid);
493             sb.append(", frequency=" + frequency);
494             sb.append(", channelWidth=" + channelWidth);
495             sb.append(", centerFreq0=" + centerFreq0);
496             sb.append(", centerFreq1=" + centerFreq1);
497             sb.append(", num_samples=" + num_samples);
498             sb.append(", num_retries=" + num_retries);
499             sb.append(", numberBurst=" + numberBurst);
500             sb.append(", interval=" + interval);
501             sb.append(", numSamplesPerBurst=" + numSamplesPerBurst);
502             sb.append(", numRetriesPerMeasurementFrame=" + numRetriesPerMeasurementFrame);
503             sb.append(", numRetriesPerFTMR=" + numRetriesPerFTMR);
504             sb.append(", LCIRequest=" + LCIRequest);
505             sb.append(", LCRRequest=" + LCRRequest);
506             sb.append(", burstTimeout=" + burstTimeout);
507             sb.append(", preamble=" + preamble);
508             sb.append(", bandwidth=" + bandwidth);
509             return sb.toString();
510         }
511     }
512 
513     /** pseudo-private class used to parcel arguments */
514     public static class ParcelableRttParams implements Parcelable {
515 
516         @NonNull
517         public RttParams mParams[];
518 
519         /**
520          * @hide
521          */
522         @VisibleForTesting
ParcelableRttParams(RttParams[] params)523         public ParcelableRttParams(RttParams[] params) {
524             mParams = (params == null ? new RttParams[0] : params);
525         }
526 
527         /** Implement the Parcelable interface {@hide} */
528         @Override
describeContents()529         public int describeContents() {
530             return 0;
531         }
532 
533         /** Implement the Parcelable interface {@hide} */
534         @Override
writeToParcel(Parcel dest, int flags)535         public void writeToParcel(Parcel dest, int flags) {
536             dest.writeInt(mParams.length);
537 
538             for (RttParams params : mParams) {
539                 dest.writeInt(params.deviceType);
540                 dest.writeInt(params.requestType);
541                 dest.writeByte(params.secure ? (byte) 1 : 0);
542                 dest.writeString(params.bssid);
543                 dest.writeInt(params.channelWidth);
544                 dest.writeInt(params.frequency);
545                 dest.writeInt(params.centerFreq0);
546                 dest.writeInt(params.centerFreq1);
547                 dest.writeInt(params.numberBurst);
548                 dest.writeInt(params.interval);
549                 dest.writeInt(params.numSamplesPerBurst);
550                 dest.writeInt(params.numRetriesPerMeasurementFrame);
551                 dest.writeInt(params.numRetriesPerFTMR);
552                 dest.writeInt(params.LCIRequest ? 1 : 0);
553                 dest.writeInt(params.LCRRequest ? 1 : 0);
554                 dest.writeInt(params.burstTimeout);
555                 dest.writeInt(params.preamble);
556                 dest.writeInt(params.bandwidth);
557             }
558         }
559 
560         /** Implement the Parcelable interface {@hide} */
561         public static final Creator<ParcelableRttParams> CREATOR =
562                 new Creator<ParcelableRttParams>() {
563                     @Override
564                     public ParcelableRttParams createFromParcel(Parcel in) {
565 
566                         int num = in.readInt();
567                         RttParams params[] = new RttParams[num];
568                         for (int i = 0; i < num; i++) {
569                             params[i] = new RttParams();
570                             params[i].deviceType = in.readInt();
571                             params[i].requestType = in.readInt();
572                             params[i].secure = (in.readByte() != 0);
573                             params[i].bssid = in.readString();
574                             params[i].channelWidth = in.readInt();
575                             params[i].frequency = in.readInt();
576                             params[i].centerFreq0 = in.readInt();
577                             params[i].centerFreq1 = in.readInt();
578                             params[i].numberBurst = in.readInt();
579                             params[i].interval = in.readInt();
580                             params[i].numSamplesPerBurst = in.readInt();
581                             params[i].numRetriesPerMeasurementFrame = in.readInt();
582                             params[i].numRetriesPerFTMR = in.readInt();
583                             params[i].LCIRequest = (in.readInt() == 1);
584                             params[i].LCRRequest = (in.readInt() == 1);
585                             params[i].burstTimeout = in.readInt();
586                             params[i].preamble = in.readInt();
587                             params[i].bandwidth = in.readInt();
588                         }
589 
590                         ParcelableRttParams parcelableParams = new ParcelableRttParams(params);
591                         return parcelableParams;
592                     }
593 
594                     @Override
595                     public ParcelableRttParams[] newArray(int size) {
596                         return new ParcelableRttParams[size];
597                     }
598                 };
599     }
600 
601     public static class WifiInformationElement {
602         /** Information Element ID 0xFF means element is invalid. */
603         public byte id;
604         public byte[] data;
605     }
606     /** specifies RTT results */
607     public static class RttResult {
608         /** mac address of the device being ranged. */
609         public String bssid;
610 
611         /** # of burst for this measurement. */
612         public int burstNumber;
613 
614         /** total number of measurement frames attempted in this measurement. */
615         public int measurementFrameNumber;
616 
617         /** total successful number of measurement frames in this measurement. */
618         public int successMeasurementFrameNumber;
619 
620         /**
621          * Maximum number of frames per burst supported by peer. Two side RTT only
622          * Valid only if less than request
623          */
624         public int frameNumberPerBurstPeer;
625 
626         /** status of the request */
627         public int status;
628 
629         /**
630          * type of the request used
631          * @deprecated Use {@link android.net.wifi.RttManager.RttResult#measurementType}
632          */
633         @Deprecated
634         public int requestType;
635 
636         /** RTT measurement method type used, should be one of RTT_TYPE_ONE_SIDED or
637          *  RTT_TYPE_TWO_SIDED.
638          */
639         public int measurementType;
640 
641         /**
642          * only valid when status ==  RTT_STATUS_FAIL_BUSY_TRY_LATER
643          * please retry RTT measurement after this duration since peer indicate busy at ths moment
644          *  Unit S  Range:1-31
645          */
646         public int retryAfterDuration;
647 
648         /** timestamp of completion, in microsecond since boot. */
649         public long ts;
650 
651         /** average RSSI observed, unit of 0.5 dB. */
652         public int rssi;
653 
654         /**
655          * RSSI spread (i.e. max - min)
656          * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rssiSpread} API.
657          */
658         @Deprecated
659         public int rssi_spread;
660 
661         /**RSSI spread (i.e. max - min), unit of 0.5 dB. */
662         public int rssiSpread;
663 
664         /**
665          * average transmit rate
666          * @deprecated Use {@link android.net.wifi.RttManager.RttResult#txRate} API.
667          */
668         @Deprecated
669         public int tx_rate;
670 
671         /** average transmit rate. Unit (kbps). */
672         public int txRate;
673 
674         /** average receiving rate Unit (kbps). */
675         public int rxRate;
676 
677        /**
678         * average round trip time in nano second
679         * @deprecated  Use {@link android.net.wifi.RttManager.RttResult#rtt} API.
680         */
681         @Deprecated
682         public long rtt_ns;
683 
684         /** average round trip time in picoseconds. */
685         public long rtt;
686 
687         /**
688          * standard deviation observed in round trip time
689          * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rttStandardDeviation} API.
690          */
691         @Deprecated
692         public long rtt_sd_ns;
693 
694         /** standard deviation of RTT in picoseconds. */
695         public long rttStandardDeviation;
696 
697         /**
698          * spread (i.e. max - min) round trip time
699          * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rttSpread} API.
700          */
701         @Deprecated
702         public long rtt_spread_ns;
703 
704         /** spread (i.e. max - min) RTT in picoseconds. */
705         public long rttSpread;
706 
707         /**
708          * average distance in centimeter, computed based on rtt_ns
709          * @deprecated use {@link android.net.wifi.RttManager.RttResult#distance} API.
710          */
711         @Deprecated
712         public int distance_cm;
713 
714         /** average distance in cm, computed based on rtt. */
715         public int distance;
716 
717         /**
718          * standard deviation observed in distance
719          * @deprecated
720          * Use {@link .android.net.wifi.RttManager.RttResult#distanceStandardDeviation} API.
721          */
722         @Deprecated
723         public int distance_sd_cm;
724 
725         /** standard deviation observed in distance in cm. */
726         public int distanceStandardDeviation;
727 
728         /**
729          * spread (i.e. max - min) distance
730          * @deprecated Use {@link android.net.wifi.RttManager.RttResult#distanceSpread} API.
731          */
732         @Deprecated
733         public int distance_spread_cm;
734 
735         /** spread (i.e. max - min) distance in cm. */
736         public int distanceSpread;
737 
738         /** the duration of this measurement burst, unit ms. */
739         public int burstDuration;
740 
741         /** Burst number supported by peer after negotiation, 2side RTT only*/
742         public int negotiatedBurstNum;
743 
744         /** LCI information Element, only available for double side RTT. */
745         public WifiInformationElement LCI;
746 
747         /** LCR information Element, only available to double side RTT. */
748         public WifiInformationElement LCR;
749 
750         /**
751          * Whether the secure RTT protocol was used for ranging.
752          */
753         public boolean secure;
754     }
755 
756 
757     /** pseudo-private class used to parcel results. */
758     public static class ParcelableRttResults implements Parcelable {
759 
760         public RttResult mResults[];
761 
ParcelableRttResults(RttResult[] results)762         public ParcelableRttResults(RttResult[] results) {
763             mResults = results;
764         }
765 
766         /**
767          * {@hide}
768          */
toString()769         public String toString() {
770             StringBuilder sb = new StringBuilder();
771             for (int i = 0; i < mResults.length; ++i) {
772                 sb.append("[" + i + "]: ");
773                 sb.append("bssid=" + mResults[i].bssid);
774                 sb.append(", burstNumber=" + mResults[i].burstNumber);
775                 sb.append(", measurementFrameNumber=" + mResults[i].measurementFrameNumber);
776                 sb.append(", successMeasurementFrameNumber="
777                         + mResults[i].successMeasurementFrameNumber);
778                 sb.append(", frameNumberPerBurstPeer=" + mResults[i].frameNumberPerBurstPeer);
779                 sb.append(", status=" + mResults[i].status);
780                 sb.append(", requestType=" + mResults[i].requestType);
781                 sb.append(", measurementType=" + mResults[i].measurementType);
782                 sb.append(", retryAfterDuration=" + mResults[i].retryAfterDuration);
783                 sb.append(", ts=" + mResults[i].ts);
784                 sb.append(", rssi=" + mResults[i].rssi);
785                 sb.append(", rssi_spread=" + mResults[i].rssi_spread);
786                 sb.append(", rssiSpread=" + mResults[i].rssiSpread);
787                 sb.append(", tx_rate=" + mResults[i].tx_rate);
788                 sb.append(", txRate=" + mResults[i].txRate);
789                 sb.append(", rxRate=" + mResults[i].rxRate);
790                 sb.append(", rtt_ns=" + mResults[i].rtt_ns);
791                 sb.append(", rtt=" + mResults[i].rtt);
792                 sb.append(", rtt_sd_ns=" + mResults[i].rtt_sd_ns);
793                 sb.append(", rttStandardDeviation=" + mResults[i].rttStandardDeviation);
794                 sb.append(", rtt_spread_ns=" + mResults[i].rtt_spread_ns);
795                 sb.append(", rttSpread=" + mResults[i].rttSpread);
796                 sb.append(", distance_cm=" + mResults[i].distance_cm);
797                 sb.append(", distance=" + mResults[i].distance);
798                 sb.append(", distance_sd_cm=" + mResults[i].distance_sd_cm);
799                 sb.append(", distanceStandardDeviation=" + mResults[i].distanceStandardDeviation);
800                 sb.append(", distance_spread_cm=" + mResults[i].distance_spread_cm);
801                 sb.append(", distanceSpread=" + mResults[i].distanceSpread);
802                 sb.append(", burstDuration=" + mResults[i].burstDuration);
803                 sb.append(", negotiatedBurstNum=" + mResults[i].negotiatedBurstNum);
804                 sb.append(", LCI=" + mResults[i].LCI);
805                 sb.append(", LCR=" + mResults[i].LCR);
806                 sb.append(", secure=" + mResults[i].secure);
807             }
808             return sb.toString();
809         }
810 
811         /** Implement the Parcelable interface {@hide} */
812         @Override
describeContents()813         public int describeContents() {
814             return 0;
815         }
816 
817         /** Implement the Parcelable interface {@hide} */
818         @Override
writeToParcel(Parcel dest, int flags)819         public void writeToParcel(Parcel dest, int flags) {
820             if (mResults != null) {
821                 dest.writeInt(mResults.length);
822                 for (RttResult result : mResults) {
823                     dest.writeString(result.bssid);
824                     dest.writeInt(result.burstNumber);
825                     dest.writeInt(result.measurementFrameNumber);
826                     dest.writeInt(result.successMeasurementFrameNumber);
827                     dest.writeInt(result.frameNumberPerBurstPeer);
828                     dest.writeInt(result.status);
829                     dest.writeInt(result.measurementType);
830                     dest.writeInt(result.retryAfterDuration);
831                     dest.writeLong(result.ts);
832                     dest.writeInt(result.rssi);
833                     dest.writeInt(result.rssiSpread);
834                     dest.writeInt(result.txRate);
835                     dest.writeLong(result.rtt);
836                     dest.writeLong(result.rttStandardDeviation);
837                     dest.writeLong(result.rttSpread);
838                     dest.writeInt(result.distance);
839                     dest.writeInt(result.distanceStandardDeviation);
840                     dest.writeInt(result.distanceSpread);
841                     dest.writeInt(result.burstDuration);
842                     dest.writeInt(result.negotiatedBurstNum);
843                     dest.writeByte(result.LCI.id);
844                     if (result.LCI.id != (byte) 0xFF) {
845                         dest.writeByte((byte)result.LCI.data.length);
846                         dest.writeByteArray(result.LCI.data);
847                     }
848                     dest.writeByte(result.LCR.id);
849                     if (result.LCR.id != (byte) 0xFF) {
850                         dest.writeByte((byte) result.LCR.data.length);
851                         dest.writeByteArray(result.LCR.data);
852                     }
853                     dest.writeByte(result.secure ? (byte) 1 : 0);
854                 }
855             } else {
856                 dest.writeInt(0);
857             }
858         }
859 
860         /** Implement the Parcelable interface {@hide} */
861         public static final Creator<ParcelableRttResults> CREATOR =
862                 new Creator<ParcelableRttResults>() {
863                     @Override
864                     public ParcelableRttResults createFromParcel(Parcel in) {
865 
866                         int num = in.readInt();
867 
868                         if (num == 0) {
869                             return new ParcelableRttResults(null);
870                         }
871 
872                         RttResult results[] = new RttResult[num];
873                         for (int i = 0; i < num; i++) {
874                             results[i] = new RttResult();
875                             results[i].bssid = in.readString();
876                             results[i].burstNumber = in.readInt();
877                             results[i].measurementFrameNumber = in.readInt();
878                             results[i].successMeasurementFrameNumber = in.readInt();
879                             results[i].frameNumberPerBurstPeer = in.readInt();
880                             results[i].status = in.readInt();
881                             results[i].measurementType = in.readInt();
882                             results[i].retryAfterDuration = in.readInt();
883                             results[i].ts = in.readLong();
884                             results[i].rssi = in.readInt();
885                             results[i].rssiSpread = in.readInt();
886                             results[i].txRate = in.readInt();
887                             results[i].rtt = in.readLong();
888                             results[i].rttStandardDeviation = in.readLong();
889                             results[i].rttSpread = in.readLong();
890                             results[i].distance = in.readInt();
891                             results[i].distanceStandardDeviation = in.readInt();
892                             results[i].distanceSpread = in.readInt();
893                             results[i].burstDuration = in.readInt();
894                             results[i].negotiatedBurstNum = in.readInt();
895                             results[i].LCI = new WifiInformationElement();
896                             results[i].LCI.id = in.readByte();
897                             if (results[i].LCI.id != (byte) 0xFF) {
898                                 byte length = in.readByte();
899                                 results[i].LCI.data = new byte[length];
900                                 in.readByteArray(results[i].LCI.data);
901                             }
902                             results[i].LCR = new WifiInformationElement();
903                             results[i].LCR.id = in.readByte();
904                             if (results[i].LCR.id != (byte) 0xFF) {
905                                 byte length = in.readByte();
906                                 results[i].LCR.data = new byte[length];
907                                 in.readByteArray(results[i].LCR.data);
908                             }
909                             results[i].secure = (in.readByte() != 0);
910                         }
911 
912                         ParcelableRttResults parcelableResults = new ParcelableRttResults(results);
913                         return parcelableResults;
914                     }
915 
916                     @Override
917                     public ParcelableRttResults[] newArray(int size) {
918                         return new ParcelableRttResults[size];
919                     }
920                 };
921     }
922 
923 
924     public static interface RttListener {
onSuccess(RttResult[] results)925         public void onSuccess(RttResult[] results);
onFailure(int reason, String description)926         public void onFailure(int reason, String description);
onAborted()927         public void onAborted();
928     }
929 
930     /**
931      * A parcelable that contains rtt client information.
932      *
933      * @hide
934      */
935     public static class RttClient implements Parcelable {
936         // Package name of RttClient.
937         private final String mPackageName;
938 
RttClient(String packageName)939         public RttClient(String packageName) {
940             mPackageName = packageName;
941         }
942 
RttClient(Parcel in)943         protected RttClient(Parcel in) {
944             mPackageName = in.readString();
945         }
946 
947         public static final Creator<RttManager.RttClient> CREATOR =
948                 new Creator<RttManager.RttClient>() {
949             @Override
950             public RttManager.RttClient createFromParcel(Parcel in) {
951                 return new RttManager.RttClient(in);
952             }
953 
954             @Override
955             public RttManager.RttClient[] newArray(int size) {
956                 return new RttManager.RttClient[size];
957             }
958         };
959 
960         @Override
describeContents()961         public int describeContents() {
962             return 0;
963         }
964 
965         @Override
writeToParcel(Parcel parcel, int i)966         public void writeToParcel(Parcel parcel, int i) {
967             parcel.writeString(mPackageName);
968         }
969 
getPackageName()970         public String getPackageName() {
971             return mPackageName;
972         }
973     }
974 
rttParamSanity(RttParams params, int index)975     private boolean rttParamSanity(RttParams params, int index) {
976         if (mRttCapabilities == null) {
977             if(getRttCapabilities() == null) {
978                 Log.e(TAG, "Can not get RTT capabilities");
979                 throw new IllegalStateException("RTT chip is not working");
980             }
981         }
982 
983         if (params.deviceType != RTT_PEER_TYPE_AP) {
984             return false;
985         } else if (params.requestType != RTT_TYPE_ONE_SIDED && params.requestType !=
986                 RTT_TYPE_TWO_SIDED) {
987             Log.e(TAG, "Request " + index + ": Illegal Request Type: " + params.requestType);
988             return false;
989         } else if (params.requestType == RTT_TYPE_ONE_SIDED &&
990                 !mRttCapabilities.oneSidedRttSupported) {
991             Log.e(TAG, "Request " + index + ": One side RTT is not supported");
992             return false;
993         } else if (params.requestType == RTT_TYPE_TWO_SIDED &&
994                 !mRttCapabilities.twoSided11McRttSupported) {
995             Log.e(TAG, "Request " + index + ": two side RTT is not supported");
996             return false;
997         }  else if(params.bssid == null || params.bssid.isEmpty()) {
998             Log.e(TAG,"No BSSID in params");
999             return false;
1000         } else if ( params.numberBurst != 0 ) {
1001             Log.e(TAG, "Request " + index + ": Illegal number of burst: " + params.numberBurst);
1002             return false;
1003         } else if (params.numSamplesPerBurst <= 0 || params.numSamplesPerBurst > 31) {
1004             Log.e(TAG, "Request " + index + ": Illegal sample number per burst: " +
1005                     params.numSamplesPerBurst);
1006             return false;
1007         } else if (params.numRetriesPerMeasurementFrame < 0 ||
1008                 params.numRetriesPerMeasurementFrame > 3) {
1009             Log.e(TAG, "Request " + index + ": Illegal measurement frame retry number:" +
1010                     params.numRetriesPerMeasurementFrame);
1011             return false;
1012         } else if(params.numRetriesPerFTMR < 0 ||
1013                 params.numRetriesPerFTMR > 3) {
1014             Log.e(TAG, "Request " + index + ": Illegal FTMR frame retry number:" +
1015                     params.numRetriesPerFTMR);
1016             return false;
1017         } else if (params.LCIRequest && !mRttCapabilities.lciSupported) {
1018             Log.e(TAG, "Request " + index + ": LCI is not supported");
1019             return false;
1020         } else if (params.LCRRequest && !mRttCapabilities.lcrSupported) {
1021             Log.e(TAG, "Request " + index + ": LCR is not supported");
1022             return false;
1023         } else if (params.burstTimeout < 1 ||
1024                 (params.burstTimeout > 11 && params.burstTimeout != 15)){
1025             Log.e(TAG, "Request " + index + ": Illegal burst timeout: " + params.burstTimeout);
1026             return false;
1027         } else if ((params.preamble & mRttCapabilities.preambleSupported) == 0) {
1028             Log.e(TAG, "Request " + index + ": Do not support this preamble: " + params.preamble);
1029             return false;
1030         } else if ((params.bandwidth & mRttCapabilities.bwSupported) == 0) {
1031             Log.e(TAG, "Request " + index + ": Do not support this bandwidth: " + params.bandwidth);
1032             return false;
1033         }
1034 
1035         return true;
1036     }
1037 
1038     /**
1039      * Request to start an RTT ranging
1040      *
1041      * @param params  -- RTT request Parameters
1042      * @param listener -- Call back to inform RTT result
1043      * @exception throw IllegalArgumentException when params are illegal
1044      *            throw IllegalStateException when RttCapabilities do not exist
1045      */
1046     @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
startRanging(RttParams[] params, RttListener listener)1047     public void startRanging(RttParams[] params, RttListener listener) {
1048         int index  = 0;
1049         for(RttParams rttParam : params) {
1050             if (!rttParamSanity(rttParam, index)) {
1051                 throw new IllegalArgumentException("RTT Request Parameter Illegal");
1052             }
1053             index++;
1054         }
1055         validateChannel();
1056         ParcelableRttParams parcelableParams = new ParcelableRttParams(params);
1057         Log.i(TAG, "Send RTT request to RTT Service");
1058         mAsyncChannel.sendMessage(CMD_OP_START_RANGING,
1059                 0, putListener(listener), parcelableParams);
1060     }
1061 
1062     @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
stopRanging(RttListener listener)1063     public void stopRanging(RttListener listener) {
1064         validateChannel();
1065         mAsyncChannel.sendMessage(CMD_OP_STOP_RANGING, 0, removeListener(listener));
1066     }
1067 
1068     /**
1069      * Callbacks for responder operations.
1070      * <p>
1071      * A {@link ResponderCallback} is the handle to the calling client. {@link RttManager} will keep
1072      * a reference to the callback for the entire period when responder is enabled. The same
1073      * callback as used in enabling responder needs to be passed for disabling responder.
1074      * The client can freely destroy or reuse the callback after {@link RttManager#disableResponder}
1075      * is called.
1076      */
1077     public abstract static class ResponderCallback {
1078         /** Callback when responder is enabled. */
onResponderEnabled(ResponderConfig config)1079         public abstract void onResponderEnabled(ResponderConfig config);
1080         /** Callback when enabling responder failed. */
onResponderEnableFailure(int reason)1081         public abstract void onResponderEnableFailure(int reason);
1082         // TODO: consider adding onResponderAborted once it's supported.
1083     }
1084 
1085     /**
1086      * Enable Wi-Fi RTT responder mode on the device. The enabling result will be delivered via
1087      * {@code callback}.
1088      * <p>
1089      * Note calling this method with the same callback when the responder is already enabled won't
1090      * change the responder state, a cached {@link ResponderConfig} from the last enabling will be
1091      * returned through the callback.
1092      *
1093      * @param callback Callback for responder enabling/disabling result.
1094      * @throws IllegalArgumentException If {@code callback} is null.
1095      */
1096     @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
enableResponder(ResponderCallback callback)1097     public void enableResponder(ResponderCallback callback) {
1098         if (callback == null) {
1099             throw new IllegalArgumentException("callback cannot be null");
1100         }
1101         validateChannel();
1102         int key = putListenerIfAbsent(callback);
1103         mAsyncChannel.sendMessage(CMD_OP_ENABLE_RESPONDER, 0, key);
1104     }
1105 
1106     /**
1107      * Disable Wi-Fi RTT responder mode on the device. The {@code callback} needs to be the
1108      * same one used in {@link #enableResponder(ResponderCallback)}.
1109      * <p>
1110      * Calling this method when responder isn't enabled won't have any effect. The callback can be
1111      * reused for enabling responder after this method is called.
1112      *
1113      * @param callback The same callback used for enabling responder.
1114      * @throws IllegalArgumentException If {@code callback} is null.
1115      */
1116     @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
disableResponder(ResponderCallback callback)1117     public void disableResponder(ResponderCallback callback) {
1118         if (callback == null) {
1119             throw new IllegalArgumentException("callback cannot be null");
1120         }
1121         validateChannel();
1122         int key = removeListener(callback);
1123         if (key == INVALID_KEY) {
1124             Log.e(TAG, "responder not enabled yet");
1125             return;
1126         }
1127         mAsyncChannel.sendMessage(CMD_OP_DISABLE_RESPONDER, 0, key);
1128     }
1129 
1130     /**
1131      * Configuration used for RTT responder mode. The configuration information can be used by a
1132      * peer device to range the responder.
1133      *
1134      * @see ScanResult
1135      */
1136     public static class ResponderConfig implements Parcelable {
1137 
1138         // TODO: make all fields final once we can get mac address from responder HAL APIs.
1139         /**
1140          * Wi-Fi mac address used for responder mode.
1141          */
1142         public String macAddress = "";
1143 
1144         /**
1145          * The primary 20 MHz frequency (in MHz) of the channel where responder is enabled.
1146          * @see ScanResult#frequency
1147          */
1148         public int frequency;
1149 
1150         /**
1151          * Center frequency of the channel where responder is enabled on. Only in use when channel
1152          * width is at least 40MHz.
1153          * @see ScanResult#centerFreq0
1154          */
1155         public int centerFreq0;
1156 
1157         /**
1158          * Center frequency of the second segment when channel width is 80 + 80 MHz.
1159          * @see ScanResult#centerFreq1
1160          */
1161         public int centerFreq1;
1162 
1163         /**
1164          * Width of the channel where responder is enabled on.
1165          * @see ScanResult#channelWidth
1166          */
1167         public int channelWidth;
1168 
1169         /**
1170          * Preamble supported by responder.
1171          */
1172         public int preamble;
1173 
1174         @Override
toString()1175         public String toString() {
1176             StringBuilder builder = new StringBuilder();
1177             builder.append("macAddress = ").append(macAddress)
1178                     .append(" frequency = ").append(frequency)
1179                     .append(" centerFreq0 = ").append(centerFreq0)
1180                     .append(" centerFreq1 = ").append(centerFreq1)
1181                     .append(" channelWidth = ").append(channelWidth)
1182                     .append(" preamble = ").append(preamble);
1183             return builder.toString();
1184         }
1185 
1186         @Override
describeContents()1187         public int describeContents() {
1188             return 0;
1189         }
1190 
1191         @Override
writeToParcel(Parcel dest, int flags)1192         public void writeToParcel(Parcel dest, int flags) {
1193             dest.writeString(macAddress);
1194             dest.writeInt(frequency);
1195             dest.writeInt(centerFreq0);
1196             dest.writeInt(centerFreq1);
1197             dest.writeInt(channelWidth);
1198             dest.writeInt(preamble);
1199         }
1200 
1201         /** Implement {@link Parcelable} interface */
1202         public static final Parcelable.Creator<ResponderConfig> CREATOR =
1203                 new Parcelable.Creator<ResponderConfig>() {
1204             @Override
1205             public ResponderConfig createFromParcel(Parcel in) {
1206                 ResponderConfig config = new ResponderConfig();
1207                 config.macAddress = in.readString();
1208                 config.frequency = in.readInt();
1209                 config.centerFreq0 = in.readInt();
1210                 config.centerFreq1 = in.readInt();
1211                 config.channelWidth = in.readInt();
1212                 config.preamble = in.readInt();
1213                 return config;
1214             }
1215 
1216             @Override
1217             public ResponderConfig[] newArray(int size) {
1218                 return new ResponderConfig[size];
1219             }
1220         };
1221 
1222     }
1223 
1224     /* private methods */
1225     public static final int BASE = Protocol.BASE_WIFI_RTT_MANAGER;
1226 
1227     public static final int CMD_OP_START_RANGING        = BASE + 0;
1228     public static final int CMD_OP_STOP_RANGING         = BASE + 1;
1229     public static final int CMD_OP_FAILED               = BASE + 2;
1230     public static final int CMD_OP_SUCCEEDED            = BASE + 3;
1231     public static final int CMD_OP_ABORTED              = BASE + 4;
1232     public static final int CMD_OP_ENABLE_RESPONDER     = BASE + 5;
1233     public static final int CMD_OP_DISABLE_RESPONDER    = BASE + 6;
1234     public static final int
1235             CMD_OP_ENALBE_RESPONDER_SUCCEEDED           = BASE + 7;
1236     public static final int
1237             CMD_OP_ENALBE_RESPONDER_FAILED              = BASE + 8;
1238     /** @hide */
1239     public static final int CMD_OP_REG_BINDER           = BASE + 9;
1240 
1241     private static final int INVALID_KEY = 0;
1242 
1243     private final Context mContext;
1244     private final IRttManager mService;
1245     private final SparseArray mListenerMap = new SparseArray();
1246     private final Object mListenerMapLock = new Object();
1247     private final Object mCapabilitiesLock = new Object();
1248 
1249     private RttCapabilities mRttCapabilities;
1250     private int mListenerKey = 1;
1251     private AsyncChannel mAsyncChannel;
1252 
1253     /**
1254      * Create a new WifiScanner instance.
1255      * Applications will almost always want to use
1256      * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
1257      * the standard {@link android.content.Context#WIFI_RTT_SERVICE Context.WIFI_RTT_SERVICE}.
1258      * @param context the application context
1259      * @param service the Binder interface
1260      * @param looper Looper for running the callbacks.
1261      *
1262      * @hide
1263      */
RttManager(Context context, IRttManager service, Looper looper)1264     public RttManager(Context context, IRttManager service, Looper looper) {
1265         mContext = context;
1266         mService = service;
1267         Messenger messenger = null;
1268         int[] key = new int[1];
1269         try {
1270             Log.d(TAG, "Get the messenger from " + mService);
1271             messenger = mService.getMessenger(new Binder(), key);
1272         } catch (RemoteException e) {
1273             throw e.rethrowFromSystemServer();
1274         }
1275 
1276         if (messenger == null) {
1277             throw new IllegalStateException("getMessenger() returned null!  This is invalid.");
1278         }
1279 
1280         mAsyncChannel = new AsyncChannel();
1281 
1282         Handler handler = new ServiceHandler(looper);
1283         mAsyncChannel.connectSync(mContext, handler, messenger);
1284         // We cannot use fullyConnectSync because it sends the FULL_CONNECTION message
1285         // synchronously, which causes RttService to receive the wrong replyTo value.
1286         mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION,
1287                 new RttClient(context.getPackageName()));
1288         mAsyncChannel.sendMessage(CMD_OP_REG_BINDER, key[0]);
1289     }
1290 
validateChannel()1291     private void validateChannel() {
1292         if (mAsyncChannel == null) throw new IllegalStateException(
1293                 "No permission to access and change wifi or a bad initialization");
1294     }
1295 
putListener(Object listener)1296     private int putListener(Object listener) {
1297         if (listener == null) return INVALID_KEY;
1298         int key;
1299         synchronized (mListenerMapLock) {
1300             do {
1301                 key = mListenerKey++;
1302             } while (key == INVALID_KEY);
1303             mListenerMap.put(key, listener);
1304         }
1305         return key;
1306     }
1307 
1308     // Insert a listener if it doesn't exist in mListenerMap. Returns the key of the listener.
putListenerIfAbsent(Object listener)1309     private int putListenerIfAbsent(Object listener) {
1310         if (listener == null) return INVALID_KEY;
1311         synchronized (mListenerMapLock) {
1312             int key = getListenerKey(listener);
1313             if (key != INVALID_KEY) {
1314                 return key;
1315             }
1316             do {
1317                 key = mListenerKey++;
1318             } while (key == INVALID_KEY);
1319             mListenerMap.put(key, listener);
1320             return key;
1321         }
1322 
1323     }
1324 
getListener(int key)1325     private Object getListener(int key) {
1326         if (key == INVALID_KEY) return null;
1327         synchronized (mListenerMapLock) {
1328             Object listener = mListenerMap.get(key);
1329             return listener;
1330         }
1331     }
1332 
getListenerKey(Object listener)1333     private int getListenerKey(Object listener) {
1334         if (listener == null) return INVALID_KEY;
1335         synchronized (mListenerMapLock) {
1336             int index = mListenerMap.indexOfValue(listener);
1337             if (index == -1) {
1338                 return INVALID_KEY;
1339             } else {
1340                 return mListenerMap.keyAt(index);
1341             }
1342         }
1343     }
1344 
removeListener(int key)1345     private Object removeListener(int key) {
1346         if (key == INVALID_KEY) return null;
1347         synchronized (mListenerMapLock) {
1348             Object listener = mListenerMap.get(key);
1349             mListenerMap.remove(key);
1350             return listener;
1351         }
1352     }
1353 
removeListener(Object listener)1354     private int removeListener(Object listener) {
1355         int key = getListenerKey(listener);
1356         if (key == INVALID_KEY) return key;
1357         synchronized (mListenerMapLock) {
1358             mListenerMap.remove(key);
1359             return key;
1360         }
1361     }
1362 
1363     private class ServiceHandler extends Handler {
ServiceHandler(Looper looper)1364         ServiceHandler(Looper looper) {
1365             super(looper);
1366         }
1367         @Override
handleMessage(Message msg)1368         public void handleMessage(Message msg) {
1369             Log.i(TAG, "RTT manager get message: " + msg.what);
1370             switch (msg.what) {
1371                 case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
1372                     return;
1373                 case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
1374                     Log.e(TAG, "Channel connection lost");
1375                     // This will cause all further async API calls on the WifiManager
1376                     // to fail and throw an exception
1377                     mAsyncChannel = null;
1378                     getLooper().quit();
1379                     return;
1380             }
1381 
1382             Object listener = getListener(msg.arg2);
1383             if (listener == null) {
1384                 Log.e(TAG, "invalid listener key = " + msg.arg2 );
1385                 return;
1386             } else {
1387                 Log.i(TAG, "listener key = " + msg.arg2);
1388             }
1389 
1390             switch (msg.what) {
1391                 /* ActionListeners grouped together */
1392                 case CMD_OP_SUCCEEDED :
1393                     reportSuccess(listener, msg);
1394                     removeListener(msg.arg2);
1395                     break;
1396                 case CMD_OP_FAILED :
1397                     reportFailure(listener, msg);
1398                     removeListener(msg.arg2);
1399                     break;
1400                 case CMD_OP_ABORTED :
1401                     ((RttListener) listener).onAborted();
1402                     removeListener(msg.arg2);
1403                     break;
1404                 case CMD_OP_ENALBE_RESPONDER_SUCCEEDED:
1405                     ResponderConfig config = (ResponderConfig) msg.obj;
1406                     ((ResponderCallback) (listener)).onResponderEnabled(config);
1407                     break;
1408                 case CMD_OP_ENALBE_RESPONDER_FAILED:
1409                     ((ResponderCallback) (listener)).onResponderEnableFailure(msg.arg1);
1410                     removeListener(msg.arg2);
1411                     break;
1412                 default:
1413                     if (DBG) Log.d(TAG, "Ignoring message " + msg.what);
1414                     return;
1415             }
1416         }
1417 
reportSuccess(Object listener, Message msg)1418         void reportSuccess(Object listener, Message msg) {
1419             RttListener rttListener = (RttListener) listener;
1420             ParcelableRttResults parcelableResults = (ParcelableRttResults) msg.obj;
1421             ((RttListener) listener).onSuccess(parcelableResults.mResults);
1422         }
1423 
reportFailure(Object listener, Message msg)1424         void reportFailure(Object listener, Message msg) {
1425             RttListener rttListener = (RttListener) listener;
1426             Bundle bundle = (Bundle) msg.obj;
1427             ((RttListener) listener).onFailure(msg.arg1, bundle.getString(DESCRIPTION_KEY));
1428         }
1429     }
1430 
1431 }
1432 
1433