diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml
index 37bf323..0bfb650 100644
--- a/tests/cts/net/AndroidManifest.xml
+++ b/tests/cts/net/AndroidManifest.xml
@@ -21,6 +21,7 @@
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java b/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java
new file mode 100644
index 0000000..a601683
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.rtt.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.location.LocationManager;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiManager;
+import android.net.wifi.rtt.RangingResult;
+import android.net.wifi.rtt.RangingResultCallback;
+import android.net.wifi.rtt.WifiRttManager;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.HandlerThread;
+import android.test.AndroidTestCase;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Base class for Wi-Fi RTT CTS test cases. Provides a uniform configuration and event management
+ * facility.
+ */
+public class TestBase extends AndroidTestCase {
+    protected static final String TAG = "WifiRttCtsTests";
+
+    // The SSID of the test AP which supports IEEE 802.11mc
+    // TODO b/74518964: finalize correct method to refer to an AP in the test lab
+    static final String SSID_OF_TEST_AP = "standalone_rtt";
+
+    // wait for Wi-Fi RTT to become available
+    private static final int WAIT_FOR_RTT_CHANGE_SECS = 10;
+
+    // wait for Wi-Fi scan results to become available
+    private static final int WAIT_FOR_SCAN_RESULTS_SECS = 20;
+
+    protected WifiRttManager mWifiRttManager;
+    protected WifiManager mWifiManager;
+    private LocationManager mLocationManager;
+    private WifiManager.WifiLock mWifiLock;
+
+    private final HandlerThread mHandlerThread = new HandlerThread("SingleDeviceTest");
+    protected final Executor mExecutor;
+    {
+        mHandlerThread.start();
+        mExecutor = new HandlerExecutor(new Handler(mHandlerThread.getLooper()));
+    }
+
+    /**
+     * Returns a flag indicating whether or not Wi-Fi RTT should be tested. Wi-Fi RTT
+     * should be tested if the feature is supported on the current device.
+     */
+    static boolean shouldTestWifiRtt(Context context) {
+        final PackageManager pm = context.getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        if (!shouldTestWifiRtt(getContext())) {
+            return;
+        }
+
+        mLocationManager = (LocationManager) getContext().getSystemService(
+                Context.LOCATION_SERVICE);
+        assertTrue("RTT testing requires Location to be enabled",
+                mLocationManager.isLocationEnabled());
+
+        mWifiRttManager = (WifiRttManager) getContext().getSystemService(
+                Context.WIFI_RTT_RANGING_SERVICE);
+        assertNotNull("Wi-Fi RTT Manager", mWifiRttManager);
+
+        mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
+        assertNotNull("Wi-Fi Manager", mWifiManager);
+        mWifiLock = mWifiManager.createWifiLock(TAG);
+        mWifiLock.acquire();
+        if (!mWifiManager.isWifiEnabled()) {
+            mWifiManager.setWifiEnabled(true);
+        }
+
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED);
+        WifiRttBroadcastReceiver receiver = new WifiRttBroadcastReceiver();
+        mContext.registerReceiver(receiver, intentFilter);
+        if (!mWifiRttManager.isAvailable()) {
+            assertTrue("Timeout waiting for Wi-Fi RTT to change status",
+                    receiver.waitForStateChange());
+            assertTrue("Wi-Fi RTT is not available (should be)", mWifiRttManager.isAvailable());
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (!shouldTestWifiRtt(getContext())) {
+            super.tearDown();
+            return;
+        }
+
+        super.tearDown();
+    }
+
+    class WifiRttBroadcastReceiver extends BroadcastReceiver {
+        private CountDownLatch mBlocker = new CountDownLatch(1);
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED.equals(intent.getAction())) {
+                mBlocker.countDown();
+            }
+        }
+
+        boolean waitForStateChange() throws InterruptedException {
+            return mBlocker.await(WAIT_FOR_RTT_CHANGE_SECS, TimeUnit.SECONDS);
+        }
+    }
+
+    class WifiScansBroadcastReceiver extends BroadcastReceiver {
+        private CountDownLatch mBlocker = new CountDownLatch(1);
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(intent.getAction())) {
+                mBlocker.countDown();
+            }
+        }
+
+        boolean waitForStateChange() throws InterruptedException {
+            return mBlocker.await(WAIT_FOR_SCAN_RESULTS_SECS, TimeUnit.SECONDS);
+        }
+    }
+
+    class ResultCallback extends RangingResultCallback {
+        private CountDownLatch mBlocker = new CountDownLatch(1);
+        private int mCode; // 0: success, otherwise RangingResultCallback STATUS_CODE_*.
+        private List<RangingResult> mResults;
+
+        @Override
+        public void onRangingFailure(int code) {
+            mCode = code;
+            mResults = null; // not necessary since intialized to null - but for completeness
+            mBlocker.countDown();
+        }
+
+        @Override
+        public void onRangingResults(List<RangingResult> results) {
+            mCode = 0; // not necessary since initialized to 0 - but for completeness
+            mResults = results;
+            mBlocker.countDown();
+        }
+
+        /**
+         * Waits for the listener callback to be called - or an error (timeout, interruption).
+         * Returns true on callback called, false on error (timeout, interruption).
+         */
+        boolean waitForCallback() throws InterruptedException {
+            return mBlocker.await(WAIT_FOR_RTT_CHANGE_SECS, TimeUnit.SECONDS);
+        }
+
+        /**
+         * Returns the code of the callback operation. Will be 0 for success (onRangingResults
+         * called), else (if onRangingFailure called) will be one of the STATUS_CODE_* values.
+         */
+        int getCode() {
+            return mCode;
+        }
+
+        /**
+         * Returns the list of ranging results. In cases of error (getCode() != 0) will return null.
+         */
+        List<RangingResult> getResults() {
+            return mResults;
+        }
+    }
+
+    /**
+     * Start a scan and return a list of observed ScanResults (APs).
+     */
+    protected List<ScanResult> scanAps() throws InterruptedException {
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+        WifiScansBroadcastReceiver receiver = new WifiScansBroadcastReceiver();
+        mContext.registerReceiver(receiver, intentFilter);
+
+        mWifiManager.startScan();
+        receiver.waitForStateChange();
+        mContext.unregisterReceiver(receiver);
+        return mWifiManager.getScanResults();
+    }
+
+    /**
+     * Start a scan and return the test AP with the specified SSID and which supports IEEE 802.11mc.
+     * If the AP is not found re-attempts the scan maxScanRetries times (i.e. total number of
+     * scans can be maxScanRetries + 1).
+     *
+     * Returns null if test AP is not found in the specified number of scans.
+     *
+     * @param ssid The SSID of the test AP
+     * @param maxScanRetries Maximum number of scans retries (in addition to first scan).
+     */
+    protected ScanResult scanForTestAp(String ssid, int maxScanRetries)
+            throws InterruptedException {
+        int scanCount = 0;
+        while (scanCount <= maxScanRetries) {
+            for (ScanResult scanResult : scanAps()) {
+                if (!scanResult.is80211mcResponder()) {
+                    continue;
+                }
+                if (!ssid.equals(scanResult.SSID)) {
+                    continue;
+                }
+
+                return scanResult;
+            }
+
+            scanCount++;
+        }
+
+        return null;
+    }
+}
diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
new file mode 100644
index 0000000..0e6b306
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.rtt.cts;
+
+import android.content.IntentFilter;
+import android.net.wifi.ScanResult;
+import android.net.wifi.rtt.RangingRequest;
+import android.net.wifi.rtt.RangingResult;
+import android.net.wifi.rtt.WifiRttManager;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Wi-Fi RTT CTS test: range to all available Access Points which support IEEE 802.11mc.
+ */
+public class WifiRttTest extends TestBase {
+    // Max number of scan retries to do while searching for APs supporting IEEE 802.11mc
+    private static final int MAX_NUM_SCAN_RETRIES_SEARCHING_FOR_IEEE80211MC_AP = 2;
+
+    // Number of RTT measurements per AP
+    private static final int NUM_OF_RTT_ITERATIONS = 10;
+
+    // Maximum failure rate of RTT measurements (percentage)
+    private static final int MAX_FAILURE_RATE_PERCENT = 10;
+
+    // Maximum variation from the average measurement (measures consistency)
+    private static final int MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM = 1000;
+
+    // Minimum valid RSSI value
+    private static final int MIN_VALID_RSSI = -100;
+
+    /**
+     * Test Wi-Fi RTT ranging operation:
+     * - Scan for visible APs for the test AP (which is validated to support IEEE 802.11mc)
+     * - Perform N (constant) RTT operations
+     * - Validate:
+     *   - Failure ratio < threshold (constant)
+     *   - Result margin < threshold (constant)
+     */
+    public void testRangingToTestAp() throws InterruptedException {
+        if (!shouldTestWifiRtt(getContext())) {
+            return;
+        }
+
+        // Scan for IEEE 802.11mc supporting APs
+        ScanResult testAp = scanForTestAp(SSID_OF_TEST_AP,
+                MAX_NUM_SCAN_RETRIES_SEARCHING_FOR_IEEE80211MC_AP);
+        assertTrue("Cannot find test AP", testAp != null);
+
+        // Perform RTT operations
+        RangingRequest request = new RangingRequest.Builder().addAccessPoint(testAp).build();
+        List<RangingResult> allResults = new ArrayList<>();
+        int numFailures = 0;
+        int distanceSum = 0;
+        int distanceMin = 0;
+        int distanceMax = 0;
+        int[] statuses = new int[NUM_OF_RTT_ITERATIONS];
+        int[] distanceMms = new int[NUM_OF_RTT_ITERATIONS];
+        int[] distanceStdDevMms = new int[NUM_OF_RTT_ITERATIONS];
+        int[] rssis = new int[NUM_OF_RTT_ITERATIONS];
+        for (int i = 0; i < NUM_OF_RTT_ITERATIONS; ++i) {
+            ResultCallback callback = new ResultCallback();
+            mWifiRttManager.startRanging(request, mExecutor, callback);
+            assertTrue("Wi-Fi RTT results: no callback on iteration " + i,
+                    callback.waitForCallback());
+
+            List<RangingResult> currentResults = callback.getResults();
+            assertTrue("Wi-Fi RTT results: null results (onRangingFailure) on iteration " + i,
+                    currentResults != null);
+            assertTrue("Wi-Fi RTT results: unexpected # of results (expect 1) on iteration " + i,
+                    currentResults.size() == 1);
+            RangingResult result = currentResults.get(0);
+            assertTrue("Wi-Fi RTT results: invalid result (wrong BSSID) entry on iteration " + i,
+                    result.getMacAddress().toString().equals(testAp.BSSID));
+
+            allResults.add(result);
+            int status = result.getStatus();
+            statuses[i] = status;
+            if (status == RangingResult.STATUS_SUCCESS) {
+                distanceSum += result.getDistanceMm();
+                if (i == 0) {
+                    distanceMin = result.getDistanceMm();
+                    distanceMax = result.getDistanceMm();
+                } else {
+                    distanceMin = Math.min(distanceMin, result.getDistanceMm());
+                    distanceMax = Math.max(distanceMax, result.getDistanceMm());
+                }
+
+                assertTrue("Wi-Fi RTT results: invalid RSSI on iteration " + i,
+                        result.getRssi() >= MIN_VALID_RSSI);
+
+                distanceMms[i - numFailures] = result.getDistanceMm();
+                distanceStdDevMms[i - numFailures] = result.getDistanceStdDevMm();
+                rssis[i - numFailures] = result.getRssi();
+            } else {
+                numFailures++;
+            }
+        }
+
+        // Save results to log
+        int numGoodResults = NUM_OF_RTT_ITERATIONS - numFailures;
+        DeviceReportLog reportLog = new DeviceReportLog(TAG, "testRangingToTestAp");
+        reportLog.addValues("status_codes", statuses, ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.addValues("distance_mm", Arrays.copyOf(distanceMms, numGoodResults),
+                ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.addValues("distance_stddev_mm", Arrays.copyOf(distanceStdDevMms, numGoodResults),
+                ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.addValues("rssi_dbm", Arrays.copyOf(rssis, numGoodResults), ResultType.NEUTRAL,
+                ResultUnit.NONE);
+        reportLog.submit();
+
+        // Analyze results
+        assertTrue("Wi-Fi RTT failure rate exceeds threshold",
+                numFailures <= NUM_OF_RTT_ITERATIONS * MAX_FAILURE_RATE_PERCENT / 100);
+        if (numFailures != NUM_OF_RTT_ITERATIONS) {
+            double distanceAvg = distanceSum / (NUM_OF_RTT_ITERATIONS - numFailures);
+            assertTrue("Wi-Fi RTT: Variation (max direction) exceeds threshold",
+                    (distanceMax - distanceAvg) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM);
+            assertTrue("Wi-Fi RTT: Variation (min direction) exceeds threshold",
+                    (distanceAvg - distanceMin) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM);
+        }
+    }
+
+    /**
+     * Validate that on Wi-Fi RTT availability change we get a broadcast + the API returns
+     * correct status.
+     */
+    public void testAvailabilityStatusChange() throws Exception {
+        if (!shouldTestWifiRtt(getContext())) {
+            return;
+        }
+
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED);
+
+        // 1. Disable Wi-Fi
+        WifiRttBroadcastReceiver receiver1 = new WifiRttBroadcastReceiver();
+        mContext.registerReceiver(receiver1, intentFilter);
+        mWifiManager.setWifiEnabled(false);
+
+        assertTrue("Timeout waiting for Wi-Fi RTT to change status",
+                receiver1.waitForStateChange());
+        assertFalse("Wi-Fi RTT is available (should not be)", mWifiRttManager.isAvailable());
+
+        // 2. Enable Wi-Fi
+        WifiRttBroadcastReceiver receiver2 = new WifiRttBroadcastReceiver();
+        mContext.registerReceiver(receiver2, intentFilter);
+        mWifiManager.setWifiEnabled(true);
+
+        assertTrue("Timeout waiting for Wi-Fi RTT to change status",
+                receiver2.waitForStateChange());
+        assertTrue("Wi-Fi RTT is not available (should be)", mWifiRttManager.isAvailable());
+    }
+
+    /**
+     * Validate that when a request contains more range operations than allowed (by API) that we
+     * get an exception.
+     */
+    public void testRequestTooLarge() {
+        if (!shouldTestWifiRtt(getContext())) {
+            return;
+        }
+
+        RangingRequest.Builder builder = new RangingRequest.Builder();
+        for (int i = 0; i < RangingRequest.getMaxPeers() + 1; ++i) {
+            ScanResult dummy = new ScanResult();
+            dummy.BSSID = "00:01:02:03:04:05";
+            builder.addAccessPoint(dummy);
+        }
+
+        try {
+            mWifiRttManager.startRanging(builder.build(), mExecutor, new ResultCallback());
+        } catch (IllegalArgumentException e) {
+            return;
+        }
+
+        assertTrue(
+                "Did not receive expected IllegalArgumentException when tried to range to too "
+                        + "many peers",
+                false);
+    }
+}
