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