17686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandepackage android.net.wifi; 27686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 37686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandeimport android.annotation.SystemApi; 47686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandeimport android.content.Context; 5c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpandeimport android.os.Bundle; 67686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandeimport android.os.Handler; 77686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandeimport android.os.HandlerThread; 87686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandeimport android.os.Looper; 97686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandeimport android.os.Message; 107686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandeimport android.os.Messenger; 11c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpandeimport android.os.Parcel; 12c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpandeimport android.os.Parcelable; 137686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandeimport android.os.RemoteException; 147686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandeimport android.util.Log; 157686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandeimport android.util.SparseArray; 167686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 177686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandeimport com.android.internal.util.AsyncChannel; 18c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpandeimport com.android.internal.util.Protocol; 197686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 207686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandeimport java.util.concurrent.CountDownLatch; 217686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 227686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande/** @hide */ 237686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande@SystemApi 247686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpandepublic class RttManager { 257686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 267686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static final boolean DBG = true; 277686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static final String TAG = "RttManager"; 287686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 297686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_TYPE_UNSPECIFIED = 0; 307686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_TYPE_ONE_SIDED = 1; 317686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_TYPE_11_V = 2; 327686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_TYPE_11_MC = 4; 337686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 347686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_PEER_TYPE_UNSPECIFIED = 0; 357686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_PEER_TYPE_AP = 1; 367686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_PEER_TYPE_STA = 2; /* requires NAN */ 377686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 387686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_CHANNEL_WIDTH_20 = 0; 397686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_CHANNEL_WIDTH_40 = 1; 407686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_CHANNEL_WIDTH_80 = 2; 417686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_CHANNEL_WIDTH_160 = 3; 427686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_CHANNEL_WIDTH_80P80 = 4; 437686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_CHANNEL_WIDTH_5 = 5; 447686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_CHANNEL_WIDTH_10 = 6; 457686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_CHANNEL_WIDTH_UNSPECIFIED = -1; 467686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 477686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_STATUS_SUCCESS = 0; 487686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_STATUS_FAILURE = 1; 497686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_STATUS_FAIL_NO_RSP = 2; 507686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_STATUS_FAIL_REJECTED = 3; 517686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4; 527686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_STATUS_FAIL_TM_TIMEOUT = 5; 537686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6; 547686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_STATUS_FAIL_NO_CAPABILITY = 7; 557686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int RTT_STATUS_ABORTED = 8; 567686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 577686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static final int REASON_UNSPECIFIED = -1; 58c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static final int REASON_NOT_AVAILABLE = -2; 59c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static final int REASON_INVALID_LISTENER = -3; 60c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static final int REASON_INVALID_REQUEST = -4; 61c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 62c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static final String DESCRIPTION_KEY = "android.net.wifi.RttManager.Description"; 637686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 647686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public class Capabilities { 65c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public int supportedType; 66c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public int supportedPeerType; 677686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 687686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 697686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public Capabilities getCapabilities() { 707686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande return new Capabilities(); 717686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 727686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 737686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** specifies parameters for RTT request */ 747686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static class RttParams { 757686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 767686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** type of device being ranged; one of RTT_PEER_TYPE_AP or RTT_PEER_TYPE_STA */ 777686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public int deviceType; 787686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 797686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** type of RTT being sought; one of RTT_TYPE_ONE_SIDED 807686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande * RTT_TYPE_11_V or RTT_TYPE_11_MC or RTT_TYPE_UNSPECIFIED */ 817686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public int requestType; 827686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 837686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** mac address of the device being ranged */ 847686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public String bssid; 857686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 867686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** channel frequency that the device is on; optional */ 877686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public int frequency; 887686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 897686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** optional channel width. wider channels result in better accuracy, 907686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande * but they take longer time, and even get aborted may times; use 917686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande * RTT_CHANNEL_WIDTH_UNSPECIFIED if not specifying */ 927686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public int channelWidth; 937686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 947686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** number of samples to be taken */ 957686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public int num_samples; 967686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 977686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** number of retries if a sample fails */ 987686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public int num_retries; 997686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 1007686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 101c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande /** pseudo-private class used to parcel arguments */ 102c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static class ParcelableRttParams implements Parcelable { 103c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 104c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public RttParams mParams[]; 105c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 106c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande ParcelableRttParams(RttParams[] params) { 107c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande mParams = params; 108c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 109c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 110c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande /** Implement the Parcelable interface {@hide} */ 111c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public int describeContents() { 112c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande return 0; 113c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 114c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 115c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande /** Implement the Parcelable interface {@hide} */ 116c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public void writeToParcel(Parcel dest, int flags) { 117c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande if (mParams != null) { 118c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(mParams.length); 119c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 120c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande for (RttParams params : mParams) { 121c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(params.deviceType); 122c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(params.requestType); 123c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeString(params.bssid); 124c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(params.frequency); 125c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(params.channelWidth); 126c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(params.num_samples); 127c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(params.num_retries); 128c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 129c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } else { 130c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(0); 131c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 132c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 133c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 134c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande /** Implement the Parcelable interface {@hide} */ 135c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static final Creator<ParcelableRttParams> CREATOR = 136c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande new Creator<ParcelableRttParams>() { 137c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public ParcelableRttParams createFromParcel(Parcel in) { 138c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 139c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande int num = in.readInt(); 140c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 141c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande if (num == 0) { 142c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande return new ParcelableRttParams(null); 143c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 144c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 145c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande RttParams params[] = new RttParams[num]; 146c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande for (int i = 0; i < num; i++) { 147c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande params[i] = new RttParams(); 148c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande params[i].deviceType = in.readInt(); 149c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande params[i].requestType = in.readInt(); 150c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande params[i].bssid = in.readString(); 151c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande params[i].frequency = in.readInt(); 152c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande params[i].channelWidth = in.readInt(); 153c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande params[i].num_samples = in.readInt(); 154c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande params[i].num_retries = in.readInt(); 155c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 156c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 157c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 158c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande ParcelableRttParams parcelableParams = new ParcelableRttParams(params); 159c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande return parcelableParams; 160c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 161c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 162c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public ParcelableRttParams[] newArray(int size) { 163c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande return new ParcelableRttParams[size]; 164c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 165c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande }; 166c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 167c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 1687686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** specifies RTT results */ 1697686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static class RttResult { 1707686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** mac address of the device being ranged */ 1717686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public String bssid; 1727686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 1737686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** status of the request */ 1747686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public int status; 1757686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 176c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande /** type of the request used */ 177c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public int requestType; 178c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 1797686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** timestamp of completion, in microsecond since boot */ 1807686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public long ts; 1817686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 1827686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** average RSSI observed */ 1837686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public int rssi; 1847686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 1857686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** RSSI spread (i.e. max - min) */ 1867686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public int rssi_spread; 1877686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 1887686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** average transmit rate */ 1897686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public int tx_rate; 1907686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 1917686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** average round trip time in nano second */ 1927686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public long rtt_ns; 1937686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 1947686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** standard deviation observed in round trip time */ 1957686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public long rtt_sd_ns; 1967686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 1977686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** spread (i.e. max - min) round trip time */ 1987686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public long rtt_spread_ns; 1997686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 2007686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** average distance in centimeter, computed based on rtt_ns */ 201c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public int distance_cm; 2027686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 2037686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** standard deviation observed in distance */ 204c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public int distance_sd_cm; 2057686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 2067686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** spread (i.e. max - min) distance */ 207c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public int distance_spread_cm; 2087686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 2097686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 210c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 211c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande /** pseudo-private class used to parcel results */ 212c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static class ParcelableRttResults implements Parcelable { 213c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 214c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public RttResult mResults[]; 215c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 216c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public ParcelableRttResults(RttResult[] results) { 217c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande mResults = results; 218c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 219c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 220c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande /** Implement the Parcelable interface {@hide} */ 221c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public int describeContents() { 222c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande return 0; 223c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 224c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 225c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande /** Implement the Parcelable interface {@hide} */ 226c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public void writeToParcel(Parcel dest, int flags) { 227c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande if (mResults != null) { 228c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(mResults.length); 229c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande for (RttResult result : mResults) { 230c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeString(result.bssid); 231c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(result.status); 232c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(result.requestType); 233c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeLong(result.ts); 234c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(result.rssi); 235c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(result.rssi_spread); 236c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(result.tx_rate); 237c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeLong(result.rtt_ns); 238c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeLong(result.rtt_sd_ns); 239c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeLong(result.rtt_spread_ns); 240c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(result.distance_cm); 241c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(result.distance_sd_cm); 242c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(result.distance_spread_cm); 243c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 244c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } else { 245c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande dest.writeInt(0); 246c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 247c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 248c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 249c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande /** Implement the Parcelable interface {@hide} */ 250c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static final Creator<ParcelableRttResults> CREATOR = 251c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande new Creator<ParcelableRttResults>() { 252c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public ParcelableRttResults createFromParcel(Parcel in) { 253c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 254c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande int num = in.readInt(); 255c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 256c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande if (num == 0) { 257c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande return new ParcelableRttResults(null); 258c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 259c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 260c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande RttResult results[] = new RttResult[num]; 261c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande for (int i = 0; i < num; i++) { 262c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i] = new RttResult(); 263c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i].bssid = in.readString(); 264c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i].status = in.readInt(); 265c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i].requestType = in.readInt(); 266c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i].ts = in.readLong(); 267c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i].rssi = in.readInt(); 268c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i].rssi_spread = in.readInt(); 269c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i].tx_rate = in.readInt(); 270c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i].rtt_ns = in.readLong(); 271c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i].rtt_sd_ns = in.readLong(); 272c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i].rtt_spread_ns = in.readLong(); 273c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i].distance_cm = in.readInt(); 274c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i].distance_sd_cm = in.readInt(); 275c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande results[i].distance_spread_cm = in.readInt(); 276c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 277c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 278c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande ParcelableRttResults parcelableResults = new ParcelableRttResults(results); 279c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande return parcelableResults; 280c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 281c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 282c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public ParcelableRttResults[] newArray(int size) { 283c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande return new ParcelableRttResults[size]; 284c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 285c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande }; 286c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 287c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 288c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 2897686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public static interface RttListener { 290c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public void onSuccess(RttResult[] results); 2917686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public void onFailure(int reason, String description); 2927686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public void onAborted(); 2937686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 2947686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 295c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public void startRanging(RttParams[] params, RttListener listener) { 2967686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande validateChannel(); 297c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande ParcelableRttParams parcelableParams = new ParcelableRttParams(params); 298c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande sAsyncChannel.sendMessage(CMD_OP_START_RANGING, 299c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 0, putListener(listener), parcelableParams); 3007686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 3017686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3027686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public void stopRanging(RttListener listener) { 3037686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande validateChannel(); 3047686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sAsyncChannel.sendMessage(CMD_OP_STOP_RANGING, 0, removeListener(listener)); 3057686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 3067686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3077686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /* private methods */ 308c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static final int BASE = Protocol.BASE_WIFI_RTT_MANAGER; 309c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 310c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static final int CMD_OP_START_RANGING = BASE + 0; 311c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static final int CMD_OP_STOP_RANGING = BASE + 1; 312c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static final int CMD_OP_FAILED = BASE + 2; 313c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static final int CMD_OP_SUCCEEDED = BASE + 3; 314c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande public static final int CMD_OP_ABORTED = BASE + 4; 3157686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3167686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private Context mContext; 3177686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private IRttManager mService; 3187686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3197686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static final int INVALID_KEY = 0; 3207686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static int sListenerKey = 1; 3217686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3227686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static final SparseArray sListenerMap = new SparseArray(); 3237686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static final Object sListenerMapLock = new Object(); 3247686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3257686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static AsyncChannel sAsyncChannel; 3267686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static CountDownLatch sConnected; 3277686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3287686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static final Object sThreadRefLock = new Object(); 3297686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static int sThreadRefCount; 3307686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static HandlerThread sHandlerThread; 3317686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3327686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /** 3337686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande * Create a new WifiScanner instance. 3347686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande * Applications will almost always want to use 3357686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve 336c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande * the standard {@link android.content.Context#WIFI_RTT_SERVICE Context.WIFI_RTT_SERVICE}. 3377686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande * @param context the application context 3387686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande * @param service the Binder interface 3397686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande * @hide 3407686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande */ 3417686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3427686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public RttManager(Context context, IRttManager service) { 3437686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande mContext = context; 3447686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande mService = service; 3457686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande init(); 3467686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 3477686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3487686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private void init() { 3497686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande synchronized (sThreadRefLock) { 3507686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (++sThreadRefCount == 1) { 3517686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande Messenger messenger = null; 3527686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande try { 353c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande Log.d(TAG, "Get the messenger from " + mService); 3547686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande messenger = mService.getMessenger(); 3557686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } catch (RemoteException e) { 3567686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /* do nothing */ 3577686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } catch (SecurityException e) { 3587686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /* do nothing */ 3597686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 3607686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3617686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (messenger == null) { 3627686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sAsyncChannel = null; 3637686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande return; 3647686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 3657686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3667686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sHandlerThread = new HandlerThread("WifiScanner"); 3677686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sAsyncChannel = new AsyncChannel(); 3687686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sConnected = new CountDownLatch(1); 3697686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3707686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sHandlerThread.start(); 3717686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande Handler handler = new ServiceHandler(sHandlerThread.getLooper()); 3727686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sAsyncChannel.connect(mContext, handler, messenger); 3737686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande try { 3747686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sConnected.await(); 3757686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } catch (InterruptedException e) { 3767686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande Log.e(TAG, "interrupted wait at init"); 3777686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 3787686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 3797686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 3807686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 3817686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3827686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private void validateChannel() { 3837686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (sAsyncChannel == null) throw new IllegalStateException( 3847686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande "No permission to access and change wifi or a bad initialization"); 3857686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 3867686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3877686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static int putListener(Object listener) { 3887686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (listener == null) return INVALID_KEY; 3897686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande int key; 3907686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande synchronized (sListenerMapLock) { 3917686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande do { 3927686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande key = sListenerKey++; 3937686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } while (key == INVALID_KEY); 3947686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sListenerMap.put(key, listener); 3957686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 3967686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande return key; 3977686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 3987686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 3997686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static Object getListener(int key) { 4007686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (key == INVALID_KEY) return null; 4017686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande synchronized (sListenerMapLock) { 4027686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande Object listener = sListenerMap.get(key); 4037686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande return listener; 4047686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4057686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4067686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 4077686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static int getListenerKey(Object listener) { 4087686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (listener == null) return INVALID_KEY; 4097686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande synchronized (sListenerMapLock) { 4107686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande int index = sListenerMap.indexOfValue(listener); 4117686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (index == -1) { 4127686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande return INVALID_KEY; 4137686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } else { 4147686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande return sListenerMap.keyAt(index); 4157686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4167686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4177686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4187686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 4197686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static Object removeListener(int key) { 4207686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (key == INVALID_KEY) return null; 4217686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande synchronized (sListenerMapLock) { 4227686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande Object listener = sListenerMap.get(key); 4237686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sListenerMap.remove(key); 4247686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande return listener; 4257686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4267686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4277686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 4287686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static int removeListener(Object listener) { 4297686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande int key = getListenerKey(listener); 4307686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (key == INVALID_KEY) return key; 4317686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande synchronized (sListenerMapLock) { 4327686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sListenerMap.remove(key); 4337686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande return key; 4347686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4357686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4367686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 4377686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande private static class ServiceHandler extends Handler { 4387686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande ServiceHandler(Looper looper) { 4397686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande super(looper); 4407686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4417686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande @Override 4427686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande public void handleMessage(Message msg) { 4437686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande switch (msg.what) { 4447686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 4457686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 4467686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); 4477686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } else { 4487686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande Log.e(TAG, "Failed to set up channel connection"); 4497686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande // This will cause all further async API calls on the WifiManager 4507686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande // to fail and throw an exception 4517686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sAsyncChannel = null; 4527686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4537686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sConnected.countDown(); 4547686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande return; 4557686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: 4567686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande return; 4577686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 4587686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande Log.e(TAG, "Channel connection lost"); 4597686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande // This will cause all further async API calls on the WifiManager 4607686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande // to fail and throw an exception 4617686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande sAsyncChannel = null; 4627686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande getLooper().quit(); 4637686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande return; 4647686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4657686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 4667686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande Object listener = getListener(msg.arg2); 4677686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (listener == null) { 4687686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (DBG) Log.d(TAG, "invalid listener key = " + msg.arg2); 4697686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande return; 4707686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } else { 4717686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (DBG) Log.d(TAG, "listener key = " + msg.arg2); 4727686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4737686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 4747686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande switch (msg.what) { 4757686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande /* ActionListeners grouped together */ 4767686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande case CMD_OP_SUCCEEDED : 477c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande reportSuccess(listener, msg); 478c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande removeListener(msg.arg2); 4797686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande break; 4807686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande case CMD_OP_FAILED : 481c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande reportFailure(listener, msg); 4827686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande removeListener(msg.arg2); 4837686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande break; 4847686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande case CMD_OP_ABORTED : 4857686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande ((RttListener) listener).onAborted(); 4867686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande removeListener(msg.arg2); 4877686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande break; 4887686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande default: 4897686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande if (DBG) Log.d(TAG, "Ignoring message " + msg.what); 4907686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande return; 4917686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 4927686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 493c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 494c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande void reportSuccess(Object listener, Message msg) { 495c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande RttListener rttListener = (RttListener) listener; 496c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande ParcelableRttResults parcelableResults = (ParcelableRttResults) msg.obj; 497c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande ((RttListener) listener).onSuccess(parcelableResults.mResults); 498c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 499c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande 500c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande void reportFailure(Object listener, Message msg) { 501c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande RttListener rttListener = (RttListener) listener; 502c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande Bundle bundle = (Bundle) msg.obj; 503c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande ((RttListener) listener).onFailure(msg.arg1, bundle.getString(DESCRIPTION_KEY)); 504c4272f32aec68ae2377141a2d6d4e6059fb36714Vinit Deshpande } 5057686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande } 5067686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 5077686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande} 5087686c061b7c5c981c79e566e3b31f68b9e21c730Vinit Deshpande 509