DO NOT MERGE - Merge pie-platform-release (PPRL.181205.001) into master

Bug: 120502534
Change-Id: Ie2c27480f248101768cb79e25ea6c10585584f14
diff --git a/prebuilts/gradle/WifiRttScan/.gitignore b/prebuilts/gradle/WifiRttScan/.gitignore
new file mode 100644
index 0000000..b90e756
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/.gitignore
@@ -0,0 +1,33 @@
+# built application files
+*.apk
+*.ap_
+
+# files for the dex VM
+*.dex
+
+# Java class files
+*.class
+
+# generated files
+bin/
+gen/
+
+# Ignore gradle files
+.gradle/
+build/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Proguard folder generated by Eclipse
+proguard/
+proguard-project.txt
+
+# Eclipse files
+.project
+.classpath
+.settings/
+
+# Android Studio/IDEA
+*.iml
+.idea
diff --git a/prebuilts/gradle/WifiRttScan/.google/packaging.yaml b/prebuilts/gradle/WifiRttScan/.google/packaging.yaml
new file mode 100644
index 0000000..f33a18a
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/.google/packaging.yaml
@@ -0,0 +1,34 @@
+# Copyright 2018 Google LLC
+#
+# 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
+#
+#     https://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.
+# GOOGLE SAMPLE PACKAGING DATA
+#
+# This file is used by Google as part of our samples packaging process.
+# End users may safely ignore this file. It has no relevance to other systems.
+---
+status:       PUBLISHED
+technologies: [Android]
+categories:   [Connectivity]
+languages:    [Java]
+solutions:    [Mobile]
+github:       android-WifiRttScan
+level:        ADVANCED
+icon:         screenshots/big_icon.png
+apiRefs:
+    - android:android.net.wifi.ScanResult
+    - android:android.net.wifi.WifiManager
+    - android:android.net.wifi.rtt.RangingRequest
+    - android:android.net.wifi.rtt.RangingResult
+    - android:android.net.wifi.rtt.RangingResultCallback
+    - android:android.net.wifi.rtt.WifiRttManager
+license: apache2
diff --git a/prebuilts/gradle/WifiRttScan/Application/build.gradle b/prebuilts/gradle/WifiRttScan/Application/build.gradle
new file mode 100644
index 0000000..4beb9cb
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/build.gradle
@@ -0,0 +1,66 @@
+
+buildscript {
+    repositories {
+        jcenter()
+        google()
+    }
+
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.2.0-beta01'
+    }
+}
+
+apply plugin: 'com.android.application'
+
+repositories {
+    jcenter()
+    google()
+}
+
+dependencies {
+
+
+    implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
+    implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha1'
+    implementation 'com.google.android.material:material:1.0.0-beta01'
+
+
+
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+    'main',     // main sample code; look here for the interesting stuff.
+    'common',   // components that are reused by multiple samples
+    'template'] // boilerplate code that is generated by the sample template process
+
+android {
+    compileSdkVersion 28
+
+    buildToolsVersion "27.0.3"
+
+    defaultConfig {
+        minSdkVersion 28
+        targetSdkVersion 28
+    }
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_7
+        targetCompatibility JavaVersion.VERSION_1_7
+    }
+
+    sourceSets {
+        main {
+            dirs.each { dir ->
+                java.srcDirs "src/${dir}/java"
+                res.srcDirs "src/${dir}/res"
+            }
+        }
+        androidTest.setRoot('tests')
+        androidTest.java.srcDirs = ['tests/src']
+
+    }
+
+}
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/AndroidManifest.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..b35cea6
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/AndroidManifest.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.wifirttscan"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-feature android:name="android.hardware.wifi.rtt" />
+
+    <!-- Permissions required for Wifi RTT. -->
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true"
+        android:theme="@style/CustomAppTheme">
+
+        <activity
+            android:name=".MainActivity"
+            android:label="@string/app_name"
+            android:theme="@style/CustomAppTheme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:name=".LocationPermissionRequestActivity"
+            android:label="@string/title_activity_location_permission_request"
+            android:parentActivityName=".MainActivity"
+            android:theme="@style/CustomAppTheme">
+        </activity>
+
+        <activity android:name=".AccessPointRangingResultsActivity"
+            android:label="@string/title_activity_access_point_ranging_results"
+            android:parentActivityName=".MainActivity"
+            android:theme="@style/CustomAppTheme">
+        </activity>
+    </application>
+</manifest>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/AccessPointRangingResultsActivity.java b/prebuilts/gradle/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/AccessPointRangingResultsActivity.java
new file mode 100644
index 0000000..eb148c9
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/AccessPointRangingResultsActivity.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2018 Google Inc. All Rights Reserved.
+ *
+ * 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 com.example.android.wifirttscan;
+
+import android.Manifest.permission;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.wifi.ScanResult;
+import android.net.wifi.rtt.RangingRequest;
+import android.net.wifi.rtt.RangingResult;
+import android.net.wifi.rtt.RangingResultCallback;
+import android.net.wifi.rtt.WifiRttManager;
+import android.os.Bundle;
+import android.os.Handler;
+import androidx.annotation.NonNull;
+import androidx.core.app.ActivityCompat;
+import androidx.appcompat.app.AppCompatActivity;
+import android.util.Log;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Displays ranging information about a particular access point chosen by the user. Uses {@link
+ * Handler} to trigger new requests based on
+ */
+public class AccessPointRangingResultsActivity extends AppCompatActivity {
+    private static final String TAG = "APRRActivity";
+
+    public static final String SCAN_RESULT_EXTRA =
+            "com.example.android.wifirttscan.extra.SCAN_RESULT";
+
+    private static final int SAMPLE_SIZE_DEFAULT = 50;
+    private static final int MILLISECONDS_DELAY_BEFORE_NEW_RANGING_REQUEST_DEFAULT = 1000;
+
+    // UI Elements.
+    private TextView mSsidTextView;
+    private TextView mBssidTextView;
+
+    private TextView mRangeTextView;
+    private TextView mRangeMeanTextView;
+    private TextView mRangeSDTextView;
+    private TextView mRangeSDMeanTextView;
+    private TextView mRssiTextView;
+    private TextView mSuccessesInBurstTextView;
+    private TextView mSuccessRatioTextView;
+    private TextView mNumberOfRequestsTextView;
+
+    private EditText mSampleSizeEditText;
+    private EditText mMillisecondsDelayBeforeNewRangingRequestEditText;
+
+    // Non UI variables.
+    private ScanResult mScanResult;
+    private String mMAC;
+
+    private int mNumberOfRangeRequests;
+    private int mNumberOfSuccessfulRangeRequests;
+
+    private int mMillisecondsDelayBeforeNewRangingRequest;
+
+    // Max sample size to calculate average for
+    // 1. Distance to device (getDistanceMm) over time
+    // 2. Standard deviation of the measured distance to the device (getDistanceStdDevMm) over time
+    // Note: A RangeRequest result already consists of the average of 7 readings from a burst,
+    // so the average in (1) is the average of these averages.
+    private int mSampleSize;
+
+    // Used to loop over a list of distances to calculate averages (ensures data structure never
+    // get larger than sample size).
+    private int mStatisticRangeHistoryEndIndex;
+    private ArrayList<Integer> mStatisticRangeHistory;
+
+    // Used to loop over a list of the standard deviation of the measured distance to calculate
+    // averages  (ensures data structure never get larger than sample size).
+    private int mStatisticRangeSDHistoryEndIndex;
+    private ArrayList<Integer> mStatisticRangeSDHistory;
+
+    private WifiRttManager mWifiRttManager;
+    private RttRangingResultCallback mRttRangingResultCallback;
+
+    // Triggers additional RangingRequests with delay (mMillisecondsDelayBeforeNewRangingRequest).
+    final Handler mRangeRequestDelayHandler = new Handler();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_access_point_ranging_results);
+
+        // Initializes UI elements.
+        mSsidTextView = findViewById(R.id.ssid);
+        mBssidTextView = findViewById(R.id.bssid);
+
+        mRangeTextView = findViewById(R.id.range_value);
+        mRangeMeanTextView = findViewById(R.id.range_mean_value);
+        mRangeSDTextView = findViewById(R.id.range_sd_value);
+        mRangeSDMeanTextView = findViewById(R.id.range_sd_mean_value);
+        mRssiTextView = findViewById(R.id.rssi_value);
+        mSuccessesInBurstTextView = findViewById(R.id.successes_in_burst_value);
+        mSuccessRatioTextView = findViewById(R.id.success_ratio_value);
+        mNumberOfRequestsTextView = findViewById(R.id.number_of_requests_value);
+
+        mSampleSizeEditText = findViewById(R.id.stats_window_size_edit_value);
+        mSampleSizeEditText.setText(SAMPLE_SIZE_DEFAULT + "");
+
+        mMillisecondsDelayBeforeNewRangingRequestEditText =
+                findViewById(R.id.ranging_period_edit_value);
+        mMillisecondsDelayBeforeNewRangingRequestEditText.setText(
+                MILLISECONDS_DELAY_BEFORE_NEW_RANGING_REQUEST_DEFAULT + "");
+
+        // Retrieve ScanResult from Intent.
+        Intent intent = getIntent();
+        mScanResult = intent.getParcelableExtra(SCAN_RESULT_EXTRA);
+
+        if (mScanResult == null) {
+            finish();
+        }
+
+        mMAC = mScanResult.BSSID;
+
+        mSsidTextView.setText(mScanResult.SSID);
+        mBssidTextView.setText(mScanResult.BSSID);
+
+        mWifiRttManager = (WifiRttManager) getSystemService(Context.WIFI_RTT_RANGING_SERVICE);
+        mRttRangingResultCallback = new RttRangingResultCallback();
+
+        // Used to store range (distance) and rangeSd (standard deviation of the measured distance)
+        // history to calculate averages.
+        mStatisticRangeHistory = new ArrayList<>();
+        mStatisticRangeSDHistory = new ArrayList<>();
+
+        resetData();
+
+        startRangingRequest();
+    }
+
+    private void resetData() {
+        mSampleSize = Integer.parseInt(mSampleSizeEditText.getText().toString());
+
+        mMillisecondsDelayBeforeNewRangingRequest =
+                Integer.parseInt(
+                        mMillisecondsDelayBeforeNewRangingRequestEditText.getText().toString());
+
+        mNumberOfSuccessfulRangeRequests = 0;
+        mNumberOfRangeRequests = 0;
+
+        mStatisticRangeHistoryEndIndex = 0;
+        mStatisticRangeHistory.clear();
+
+        mStatisticRangeSDHistoryEndIndex = 0;
+        mStatisticRangeSDHistory.clear();
+    }
+
+    private void startRangingRequest() {
+        // Permission for fine location should already be granted via MainActivity (you can't get
+        // to this class unless you already have permission. If they get to this class, then disable
+        // fine location permission, we kick them back to main activity.
+        if (ActivityCompat.checkSelfPermission(this, permission.ACCESS_FINE_LOCATION)
+                != PackageManager.PERMISSION_GRANTED) {
+            finish();
+        }
+
+        mNumberOfRangeRequests++;
+
+        RangingRequest rangingRequest =
+                new RangingRequest.Builder().addAccessPoint(mScanResult).build();
+
+        mWifiRttManager.startRanging(
+                rangingRequest, getApplication().getMainExecutor(), mRttRangingResultCallback);
+    }
+
+    // Calculates average distance based on stored history.
+    private float getDistanceMean() {
+        float distanceSum = 0;
+
+        for (int distance : mStatisticRangeHistory) {
+            distanceSum += distance;
+        }
+
+        return distanceSum / mStatisticRangeHistory.size();
+    }
+
+    // Adds distance to history. If larger than sample size value, loops back over and replaces the
+    // oldest distance record in the list.
+    private void addDistanceToHistory(int distance) {
+
+        if (mStatisticRangeHistory.size() >= mSampleSize) {
+
+            if (mStatisticRangeHistoryEndIndex >= mSampleSize) {
+                mStatisticRangeHistoryEndIndex = 0;
+            }
+
+            mStatisticRangeHistory.set(mStatisticRangeHistoryEndIndex, distance);
+            mStatisticRangeHistoryEndIndex++;
+
+        } else {
+            mStatisticRangeHistory.add(distance);
+        }
+    }
+
+    // Calculates standard deviation of the measured distance based on stored history.
+    private float getStandardDeviationOfDistanceMean() {
+        float distanceSdSum = 0;
+
+        for (int distanceSd : mStatisticRangeSDHistory) {
+            distanceSdSum += distanceSd;
+        }
+
+        return distanceSdSum / mStatisticRangeHistory.size();
+    }
+
+    // Adds standard deviation of the measured distance to history. If larger than sample size
+    // value, loops back over and replaces the oldest distance record in the list.
+    private void addStandardDeviationOfDistanceToHistory(int distanceSd) {
+
+        if (mStatisticRangeSDHistory.size() >= mSampleSize) {
+
+            if (mStatisticRangeSDHistoryEndIndex >= mSampleSize) {
+                mStatisticRangeSDHistoryEndIndex = 0;
+            }
+
+            mStatisticRangeSDHistory.set(mStatisticRangeSDHistoryEndIndex, distanceSd);
+            mStatisticRangeSDHistoryEndIndex++;
+
+        } else {
+            mStatisticRangeSDHistory.add(distanceSd);
+        }
+    }
+
+    public void onResetButtonClick(View view) {
+        resetData();
+    }
+
+    // Class that handles callbacks for all RangingRequests and issues new RangingRequests.
+    private class RttRangingResultCallback extends RangingResultCallback {
+
+        private void queueNextRangingRequest() {
+            mRangeRequestDelayHandler.postDelayed(
+                    new Runnable() {
+                        @Override
+                        public void run() {
+                            startRangingRequest();
+                        }
+                    },
+                    mMillisecondsDelayBeforeNewRangingRequest);
+        }
+
+        @Override
+        public void onRangingFailure(int code) {
+            Log.d(TAG, "onRangingFailure() code: " + code);
+            queueNextRangingRequest();
+        }
+
+        @Override
+        public void onRangingResults(@NonNull List<RangingResult> list) {
+            Log.d(TAG, "onRangingResults(): " + list);
+
+            // Because we are only requesting RangingResult for one access point (not multiple
+            // access points), this will only ever be one. (Use loops when requesting RangingResults
+            // for multiple access points.)
+            if (list.size() == 1) {
+
+                RangingResult rangingResult = list.get(0);
+
+                if (mMAC.equals(rangingResult.getMacAddress().toString())) {
+
+                    if (rangingResult.getStatus() == RangingResult.STATUS_SUCCESS) {
+
+                        mNumberOfSuccessfulRangeRequests++;
+
+                        mRangeTextView.setText((rangingResult.getDistanceMm() / 1000f) + "");
+                        addDistanceToHistory(rangingResult.getDistanceMm());
+                        mRangeMeanTextView.setText((getDistanceMean() / 1000f) + "");
+
+                        mRangeSDTextView.setText(
+                                (rangingResult.getDistanceStdDevMm() / 1000f) + "");
+                        addStandardDeviationOfDistanceToHistory(
+                                rangingResult.getDistanceStdDevMm());
+                        mRangeSDMeanTextView.setText(
+                                (getStandardDeviationOfDistanceMean() / 1000f) + "");
+
+                        mRssiTextView.setText(rangingResult.getRssi() + "");
+                        mSuccessesInBurstTextView.setText(
+                                rangingResult.getNumSuccessfulMeasurements()
+                                        + "/"
+                                        + rangingResult.getNumAttemptedMeasurements());
+
+                        float successRatio =
+                                ((float) mNumberOfSuccessfulRangeRequests
+                                                / (float) mNumberOfRangeRequests)
+                                        * 100;
+                        mSuccessRatioTextView.setText(successRatio + "%");
+
+                        mNumberOfRequestsTextView.setText(mNumberOfRangeRequests + "");
+
+                    } else if (rangingResult.getStatus()
+                            == RangingResult.STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC) {
+                        Log.d(TAG, "RangingResult failed (AP doesn't support IEEE80211 MC.");
+
+                    } else {
+                        Log.d(TAG, "RangingResult failed.");
+                    }
+
+                } else {
+                    Toast.makeText(
+                                    getApplicationContext(),
+                                    R.string
+                                            .mac_mismatch_message_activity_access_point_ranging_results,
+                                    Toast.LENGTH_LONG)
+                            .show();
+                }
+            }
+
+            queueNextRangingRequest();
+        }
+    }
+}
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/LocationPermissionRequestActivity.java b/prebuilts/gradle/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/LocationPermissionRequestActivity.java
new file mode 100644
index 0000000..170eceb
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/LocationPermissionRequestActivity.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 Google Inc. All Rights Reserved.
+ *
+ * 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 com.example.android.wifirttscan;
+
+import android.Manifest;
+import android.Manifest.permission;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import androidx.annotation.NonNull;
+import androidx.core.app.ActivityCompat;
+import androidx.appcompat.app.AppCompatActivity;
+import android.util.Log;
+import android.view.View;
+
+/**
+ * This is a simple splash screen (activity) for giving more details on why the user should approve
+ * fine location permissions. If they choose to move forward, the permission screen is brought up.
+ * Either way (approve or disapprove), this will exit to the MainActivity after they are finished
+ * with their final decision.
+ */
+public class LocationPermissionRequestActivity extends AppCompatActivity
+        implements ActivityCompat.OnRequestPermissionsResultCallback {
+
+    private static final String TAG = "LocationPermission";
+
+    /* Id to identify Location permission request. */
+    private static final int PERMISSION_REQUEST_FINE_LOCATION = 1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // If permissions granted, we start the main activity (shut this activity down).
+        if (ActivityCompat.checkSelfPermission(this, permission.ACCESS_FINE_LOCATION)
+                == PackageManager.PERMISSION_GRANTED) {
+            finish();
+        }
+
+        setContentView(R.layout.activity_location_permission_request);
+    }
+
+    public void onClickApprovePermissionRequest(View view) {
+        Log.d(TAG, "onClickApprovePermissionRequest()");
+
+        // On 23+ (M+) devices, fine location permission not granted. Request permission.
+        ActivityCompat.requestPermissions(
+                this,
+                new String[] {Manifest.permission.ACCESS_FINE_LOCATION},
+                PERMISSION_REQUEST_FINE_LOCATION);
+    }
+
+    public void onClickDenyPermissionRequest(View view) {
+        Log.d(TAG, "onClickDenyPermissionRequest()");
+        finish();
+    }
+
+    /*
+     * Callback received when a permissions request has been completed.
+     */
+    @Override
+    public void onRequestPermissionsResult(
+            int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+
+        String permissionResult =
+                "Request code: "
+                        + requestCode
+                        + ", Permissions: "
+                        + permissions
+                        + ", Results: "
+                        + grantResults;
+        Log.d(TAG, "onRequestPermissionsResult(): " + permissionResult);
+
+        if (requestCode == PERMISSION_REQUEST_FINE_LOCATION) {
+            // Close activity regardless of user's decision (decision picked up in main activity).
+            finish();
+        }
+    }
+}
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MainActivity.java b/prebuilts/gradle/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MainActivity.java
new file mode 100644
index 0000000..b6905bf
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MainActivity.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2018 Google Inc. All Rights Reserved.
+ *
+ * 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 com.example.android.wifirttscan;
+
+import static com.example.android.wifirttscan.AccessPointRangingResultsActivity.SCAN_RESULT_EXTRA;
+
+import android.Manifest.permission;
+import android.annotation.SuppressLint;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiManager;
+import android.net.wifi.rtt.RangingRequest;
+import android.os.Bundle;
+import androidx.annotation.NonNull;
+import androidx.core.app.ActivityCompat;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView.LayoutManager;
+import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
+
+import com.example.android.wifirttscan.MyAdapter.ScanResultClickListener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Displays list of Access Points enabled with WifiRTT (to check distance). Requests location
+ * permissions if they are not approved via secondary splash screen explaining why they are needed.
+ */
+public class MainActivity extends AppCompatActivity implements ScanResultClickListener {
+
+    private static final String TAG = "MainActivity";
+
+    private boolean mLocationPermissionApproved = false;
+
+    List<ScanResult> mAccessPointsSupporting80211mc;
+
+    private WifiManager mWifiManager;
+    private WifiScanReceiver mWifiScanReceiver;
+
+    private TextView mOutputTextView;
+    private RecyclerView mRecyclerView;
+
+    private MyAdapter mAdapter;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        mOutputTextView = findViewById(R.id.access_point_summary_text_view);
+        mRecyclerView = findViewById(R.id.recycler_view);
+
+        // Improve performance if you know that changes in content do not change the layout size
+        // of the RecyclerView
+        mRecyclerView.setHasFixedSize(true);
+
+        // use a linear layout manager
+        LayoutManager layoutManager = new LinearLayoutManager(this);
+        mRecyclerView.setLayoutManager(layoutManager);
+
+        mAccessPointsSupporting80211mc = new ArrayList<>();
+
+        mAdapter = new MyAdapter(mAccessPointsSupporting80211mc, this);
+        mRecyclerView.setAdapter(mAdapter);
+
+        mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+        mWifiScanReceiver = new WifiScanReceiver();
+    }
+
+    @Override
+    protected void onResume() {
+        Log.d(TAG, "onResume()");
+        super.onResume();
+
+        mLocationPermissionApproved =
+                ActivityCompat.checkSelfPermission(this, permission.ACCESS_FINE_LOCATION)
+                        == PackageManager.PERMISSION_GRANTED;
+
+        registerReceiver(
+                mWifiScanReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
+    }
+
+    @Override
+    protected void onPause() {
+        Log.d(TAG, "onPause()");
+        super.onPause();
+        unregisterReceiver(mWifiScanReceiver);
+    }
+
+    private void logToUi(final String message) {
+        if (!message.isEmpty()) {
+            Log.d(TAG, message);
+            mOutputTextView.setText(message);
+        }
+    }
+
+    @Override
+    public void onScanResultItemClick(ScanResult scanResult) {
+        Log.d(TAG, "onScanResultItemClick(): ssid: " + scanResult.SSID);
+
+        Intent intent = new Intent(this, AccessPointRangingResultsActivity.class);
+        intent.putExtra(SCAN_RESULT_EXTRA, scanResult);
+        startActivity(intent);
+    }
+
+    public void onClickFindDistancesToAccessPoints(View view) {
+        if (mLocationPermissionApproved) {
+            logToUi(getString(R.string.retrieving_access_points));
+            mWifiManager.startScan();
+
+        } else {
+            // On 23+ (M+) devices, fine location permission not granted. Request permission.
+            Intent startIntent = new Intent(this, LocationPermissionRequestActivity.class);
+            startActivity(startIntent);
+        }
+    }
+
+    private class WifiScanReceiver extends BroadcastReceiver {
+
+        private List<ScanResult> find80211mcSupportedAccessPoints(
+                @NonNull List<ScanResult> originalList) {
+            List<ScanResult> newList = new ArrayList<>();
+
+            for (ScanResult scanResult : originalList) {
+
+                if (scanResult.is80211mcResponder()) {
+                    newList.add(scanResult);
+                }
+
+                if (newList.size() >= RangingRequest.getMaxPeers()) {
+                    break;
+                }
+            }
+            return newList;
+        }
+
+        // This is checked via mLocationPermissionApproved boolean
+        @SuppressLint("MissingPermission")
+        public void onReceive(Context context, Intent intent) {
+
+            List<ScanResult> scanResults = mWifiManager.getScanResults();
+
+            if (scanResults != null) {
+
+                if (mLocationPermissionApproved) {
+                    mAccessPointsSupporting80211mc = find80211mcSupportedAccessPoints(scanResults);
+
+                    mAdapter.swapData(mAccessPointsSupporting80211mc);
+
+                    logToUi(
+                            scanResults.size()
+                                    + " APs discovered, "
+                                    + mAccessPointsSupporting80211mc.size()
+                                    + " RTT capable.");
+
+                } else {
+                    // TODO (jewalker): Add Snackbar regarding permissions
+                    Log.d(TAG, "Permissions not allowed.");
+                }
+            }
+        }
+    }
+}
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MyAdapter.java b/prebuilts/gradle/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MyAdapter.java
new file mode 100644
index 0000000..2b84681
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MyAdapter.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2018 Google Inc. All Rights Reserved.
+ *
+ * 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 com.example.android.wifirttscan;
+
+import android.net.wifi.ScanResult;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.List;
+
+/**
+ * Displays the ssid and bssid from a list of {@link ScanResult}s including a header at the top of
+ * the {@link RecyclerView} to label the data.
+ */
+public class MyAdapter extends RecyclerView.Adapter<ViewHolder> {
+    private static final int HEADER_POSITION = 0;
+
+    private static final int TYPE_HEADER = 0;
+    private static final int TYPE_ITEM = 1;
+
+    private static ScanResultClickListener sScanResultClickListener;
+
+    private List<ScanResult> mWifiAccessPointsWithRtt;
+
+    public MyAdapter(List<ScanResult> list, ScanResultClickListener scanResultClickListener) {
+        mWifiAccessPointsWithRtt = list;
+        sScanResultClickListener = scanResultClickListener;
+    }
+
+    public static class ViewHolderHeader extends RecyclerView.ViewHolder {
+        public ViewHolderHeader(View view) {
+            super(view);
+        }
+    }
+
+    public class ViewHolderItem extends RecyclerView.ViewHolder implements View.OnClickListener {
+        public TextView mSsidTextView;
+        public TextView mBssidTextView;
+
+        public ViewHolderItem(View view) {
+            super(view);
+            view.setOnClickListener(this);
+            mSsidTextView = view.findViewById(R.id.ssid_text_view);
+            mBssidTextView = view.findViewById(R.id.bssid_text_view);
+        }
+
+        @Override
+        public void onClick(View view) {
+            sScanResultClickListener.onScanResultItemClick(getItem(getAdapterPosition()));
+        }
+    }
+
+    public void swapData(List<ScanResult> list) {
+
+        // Always clear with any update, as even an empty list means no WifiRtt devices were found.
+        mWifiAccessPointsWithRtt.clear();
+
+        if ((list != null) && (list.size() > 0)) {
+            mWifiAccessPointsWithRtt.addAll(list);
+        }
+
+        notifyDataSetChanged();
+    }
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+
+        ViewHolder viewHolder;
+
+        if (viewType == TYPE_HEADER) {
+            viewHolder =
+                    new ViewHolderHeader(
+                            LayoutInflater.from(parent.getContext())
+                                    .inflate(R.layout.recycler_row_header, parent, false));
+
+        } else if (viewType == TYPE_ITEM) {
+            viewHolder =
+                    new ViewHolderItem(
+                            LayoutInflater.from(parent.getContext())
+                                    .inflate(R.layout.recycler_row_item, parent, false));
+        } else {
+            throw new RuntimeException(viewType + " isn't a valid view type.");
+        }
+
+        return viewHolder;
+    }
+
+    @Override
+    public void onBindViewHolder(ViewHolder viewHolder, int position) {
+
+        if (viewHolder instanceof ViewHolderHeader) {
+            // No updates need to be made to header view (defaults remain same).
+
+        } else if (viewHolder instanceof ViewHolderItem) {
+            ViewHolderItem viewHolderItem = (ViewHolderItem) viewHolder;
+            ScanResult currentScanResult = getItem(position);
+
+            viewHolderItem.mSsidTextView.setText(currentScanResult.SSID);
+            viewHolderItem.mBssidTextView.setText(currentScanResult.BSSID);
+
+        } else {
+            throw new RuntimeException(viewHolder + " isn't a valid view holder.");
+        }
+    }
+
+    /*
+     * Because we added a header item to the list, we need to decrement the position by one to get
+     * the proper place in the list.
+     */
+    private ScanResult getItem(int position) {
+        return mWifiAccessPointsWithRtt.get(position - 1);
+    }
+
+    // Returns size of list plus the header item (adds extra item).
+    @Override
+    public int getItemCount() {
+        return mWifiAccessPointsWithRtt.size() + 1;
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        if (position == HEADER_POSITION) {
+            return TYPE_HEADER;
+        } else {
+            return TYPE_ITEM;
+        }
+    }
+
+    // Used to inform the class containing the RecyclerView that one of the ScanResult items in the
+    // list was clicked.
+    public interface ScanResultClickListener {
+        void onScanResultItemClick(ScanResult scanResult);
+    }
+}
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-hdpi/ic_wifi.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-hdpi/ic_wifi.png
new file mode 100644
index 0000000..b768a95
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-hdpi/ic_wifi.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-mdpi/ic_wifi.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-mdpi/ic_wifi.png
new file mode 100644
index 0000000..e13fb0f
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-mdpi/ic_wifi.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-v24/ic_launcher_foreground.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..ae56de1
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 Google Inc. All rights reserved.
+  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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+    <path
+        android:fillType="evenOdd"
+        android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
+        android:strokeColor="#00000000"
+        android:strokeWidth="1">
+        <aapt:attr name="android:fillColor">
+            <gradient
+                android:endX="78.5885"
+                android:endY="90.9159"
+                android:startX="48.7653"
+                android:startY="61.0927"
+                android:type="linear">
+                <item
+                    android:color="#44000000"
+                    android:offset="0.0" />
+                <item
+                    android:color="#00000000"
+                    android:offset="1.0" />
+            </gradient>
+        </aapt:attr>
+    </path>
+    <path
+        android:fillColor="#FFFFFF"
+        android:fillType="nonZero"
+        android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
+        android:strokeColor="#00000000"
+        android:strokeWidth="1" />
+</vector>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-xhdpi/ic_wifi.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-xhdpi/ic_wifi.png
new file mode 100644
index 0000000..ecb6564
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-xhdpi/ic_wifi.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-xxhdpi/ic_wifi.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-xxhdpi/ic_wifi.png
new file mode 100644
index 0000000..91ecfbe
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable-xxhdpi/ic_wifi.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable/ic_launcher_background.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..0d5ac30
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 Google Inc. All rights reserved.
+  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.
+  -->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+    <path
+        android:fillColor="#26A69A"
+        android:pathData="M0,0h108v108h-108z" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M9,0L9,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,0L19,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,0L29,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,0L39,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,0L49,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,0L59,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,0L69,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,0L79,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M89,0L89,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M99,0L99,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,9L108,9"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,19L108,19"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,29L108,29"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,39L108,39"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,49L108,49"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,59L108,59"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,69L108,69"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,79L108,79"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,89L108,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,99L108,99"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,29L89,29"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,39L89,39"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,49L89,49"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,59L89,59"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,69L89,69"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,79L89,79"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,19L29,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,19L39,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,19L49,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,19L59,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,19L69,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,19L79,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+</vector>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable/ic_round_network_wifi_24px.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable/ic_round_network_wifi_24px.xml
new file mode 100644
index 0000000..d983049
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable/ic_round_network_wifi_24px.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 Google Inc. All rights reserved.
+  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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:fillColor="#FF000000"
+      android:pathData="M23.64,7C23.19,6.66 18.71,3 12,3C5.28,3 0.81,6.66 0.36,7l10.08,12.56c0.8,1 2.32,1 3.12,0L23.64,7z"
+      android:fillAlpha="0.3"/>
+  <path
+      android:fillColor="#FF000000"
+      android:pathData="M3.53,10.94l6.91,8.61c0.8,1 2.32,1 3.12,0l6.91,-8.61c-0.43,-0.33 -3.66,-2.95 -8.47,-2.95S3.96,10.61 3.53,10.94z"/>
+</vector>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable/ic_round_network_wifi_white_24px.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable/ic_round_network_wifi_white_24px.xml
new file mode 100644
index 0000000..e392b05
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/drawable/ic_round_network_wifi_white_24px.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 Google Inc. All rights reserved.
+  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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:pathData="M23.64,7C23.19,6.66 18.71,3 12,3C5.28,3 0.81,6.66 0.36,7l10.08,12.56c0.8,1 2.32,1 3.12,0L23.64,7z"
+      android:fillColor="#ffffff"
+      android:fillAlpha="0.3"/>
+  <path
+      android:pathData="M3.53,10.94l6.91,8.61c0.8,1 2.32,1 3.12,0l6.91,-8.61c-0.43,-0.33 -3.66,-2.95 -8.47,-2.95S3.96,10.61 3.53,10.94z"
+      android:fillColor="#ffffff"/>
+</vector>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/activity_access_point_ranging_results.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/activity_access_point_ranging_results.xml
new file mode 100644
index 0000000..ccd3bd8
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/activity_access_point_ranging_results.xml
@@ -0,0 +1,351 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 Google Inc. All rights reserved.
+  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.
+  -->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".AccessPointRangingResultsActivity">
+
+    <TextView
+        android:id="@+id/ssid"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top_title"
+        android:gravity="center_vertical"
+        tools:text="SSID"
+        android:textAlignment="center"
+        android:textSize="@dimen/activity_access_point_ranging_request_header_text_size"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/bssid"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top_title"
+        android:gravity="center_vertical"
+        android:textAlignment="center"
+        android:textSize="@dimen/activity_access_point_ranging_request_header_text_size"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="BSSID" />
+
+    <View
+        android:id="@+id/divider1"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/activity_access_point_ranging_request_divider_height"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top_divider"
+        android:background="?android:attr/listDivider"
+        android:visibility="visible"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/bssid" />
+
+    <TextView
+        android:id="@+id/range_label"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top_divider"
+        android:gravity="start"
+        android:text="@string/range_label_activity_access_point_ranging_results"
+        android:textAlignment="textStart"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/divider1" />
+
+    <TextView
+        android:id="@+id/range_value"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top_divider"
+        android:gravity="end"
+        android:text="@string/activity_access_point_ranging_results_requesting_default"
+        android:textAlignment="textEnd"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/divider1" />
+
+    <TextView
+        android:id="@+id/range_mean_label"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="start"
+        android:text="@string/range_mean_label_activity_access_point_ranging_results"
+        android:textAlignment="textStart"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/range_label" />
+
+    <TextView
+        android:id="@+id/range_mean_value"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="end"
+        android:text="@string/activity_access_point_ranging_results_requesting_default"
+        android:textAlignment="textEnd"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/range_value" />
+
+    <TextView
+        android:id="@+id/range_sd_label"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="start"
+        android:text="@string/range_sd_label_activity_access_point_ranging_results"
+        android:textAlignment="textStart"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/range_mean_label" />
+
+    <TextView
+        android:id="@+id/range_sd_value"
+        android:layout_width="176dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="end"
+        android:text="@string/activity_access_point_ranging_results_requesting_default"
+        android:textAlignment="textEnd"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/range_mean_value" />
+
+    <TextView
+        android:id="@+id/range_sd_mean_label"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="start"
+        android:text="@string/range_sd_mean_activity_access_point_ranging_results"
+        android:textAlignment="textStart"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/range_sd_label" />
+
+    <TextView
+        android:id="@+id/range_sd_mean_value"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="end"
+        android:text="@string/activity_access_point_ranging_results_requesting_default"
+        android:textAlignment="textEnd"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/range_sd_value" />
+
+    <TextView
+        android:id="@+id/rssi_label"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="start"
+        android:text="@string/rssi_label_activity_access_point_ranging_results"
+        android:textAlignment="textStart"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/range_sd_mean_label" />
+
+    <TextView
+        android:id="@+id/rssi_value"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="end"
+        android:text="@string/activity_access_point_ranging_results_requesting_default"
+        android:textAlignment="textEnd"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/range_sd_mean_value" />
+
+    <TextView
+        android:id="@+id/successes_in_burst_label"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="start"
+        android:text="@string/successes_in_burst_label_activity_access_point_ranging_results"
+        android:textAlignment="textStart"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/rssi_label" />
+
+    <TextView
+        android:id="@+id/successes_in_burst_value"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="end"
+        android:text="@string/activity_access_point_ranging_results_requesting_default"
+        android:textAlignment="textEnd"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/rssi_value" />
+
+    <TextView
+        android:id="@+id/success_ratio_label"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="start"
+        android:text="@string/success_ratio_label_activity_access_point_ranging_results"
+        android:textAlignment="textStart"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/successes_in_burst_label" />
+
+    <TextView
+        android:id="@+id/success_ratio_value"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="end"
+        android:text="@string/activity_access_point_ranging_results_requesting_default"
+        android:textAlignment="textEnd"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/successes_in_burst_value" />
+
+    <TextView
+        android:id="@+id/number_of_requests_label"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="start"
+        android:text="@string/number_of_requests_label_activity_access_point_ranging_results"
+        android:textAlignment="textStart"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/success_ratio_label" />
+
+    <TextView
+        android:id="@+id/number_of_requests_value"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="end"
+        android:text="@string/activity_access_point_ranging_results_requesting_default"
+        android:textAlignment="textEnd"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/success_ratio_value" />
+
+    <View
+        android:id="@+id/divider2"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/activity_access_point_ranging_request_divider_height"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top_divider"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:background="?android:attr/listDivider"
+        android:visibility="visible"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/number_of_requests_value" />
+
+    <TextView
+        android:id="@+id/stats_window_size_label"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/activity_access_point_ranging_request_edit_view_height"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top_divider"
+        android:gravity="start"
+        android:text="@string/stats_window_size_label_activity_access_point_ranging_results"
+        android:textAlignment="textStart"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/divider2" />
+
+    <EditText
+        android:id="@+id/stats_window_size_edit_value"
+        android:layout_width="@dimen/activity_access_point_ranging_request_edit_view_width"
+        android:layout_height="@dimen/activity_access_point_ranging_request_edit_view_height"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top_divider"
+        android:ems="10"
+        android:singleLine="true"
+        android:inputType="number"
+        android:textAlignment="textEnd"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/divider2"
+        tools:text="50" />
+
+    <TextView
+        android:id="@+id/ranging_period_label"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/activity_access_point_ranging_request_edit_view_height"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:gravity="start"
+        android:text="@string/ranging_period_label_activity_access_point_ranging_results"
+        android:textAlignment="textStart"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/stats_window_size_label" />
+
+    <EditText
+        android:id="@+id/ranging_period_edit_value"
+        android:layout_width="@dimen/activity_access_point_ranging_request_edit_view_width"
+        android:layout_height="@dimen/activity_access_point_ranging_request_edit_view_height"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:layout_marginTop="@dimen/activity_access_point_ranging_request_margin_top"
+        android:ems="10"
+        android:singleLine="true"
+        android:inputType="number"
+        android:textAlignment="textEnd"
+        android:textSize="@dimen/activity_access_point_ranging_request_item_text_size"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/stats_window_size_edit_value"
+        tools:text="1000" />
+
+    <Button
+        android:id="@+id/reset_button"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="8dp"
+        android:layout_marginEnd="@dimen/activity_access_point_ranging_request_margin_end"
+        android:layout_marginStart="@dimen/activity_access_point_ranging_request_margin_start"
+        android:onClick="onResetButtonClick"
+        android:text="@string/reset_label_activity_access_point_ranging_results"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/activity_location_permission_request.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/activity_location_permission_request.xml
new file mode 100644
index 0000000..aa256c0
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/activity_location_permission_request.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 Google Inc. All rights reserved.
+  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.
+  -->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/relativeLayout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/colorSecondary"
+    tools:layout_editor_absoluteY="81dp">
+
+    <ImageView
+        android:id="@+id/imageView"
+        android:layout_width="0dp"
+        android:layout_height="140dp"
+        android:layout_marginLeft="16dp"
+        android:layout_marginRight="16dp"
+        android:layout_marginTop="48dp"
+        android:src="@drawable/ic_round_network_wifi_white_24px"
+        app:layout_constraintHorizontal_bias="0.0"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/mainMessageTextView"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="8dp"
+        android:layout_marginEnd="16dp"
+        android:layout_marginStart="16dp"
+        android:layout_marginTop="16dp"
+        android:text="@string/main_message_activity_location_permission_request"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:textColor="#ffffff"
+        android:textStyle="bold"
+        app:layout_constraintBottom_toTopOf="@+id/detailsTextView"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.0"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/imageView"
+        app:layout_constraintVertical_chainStyle="spread_inside" />
+
+    <TextView
+        android:id="@+id/detailsTextView"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_marginBottom="8dp"
+        android:layout_marginEnd="16dp"
+        android:layout_marginStart="16dp"
+        android:layout_marginTop="8dp"
+        android:text="@string/details_message_activity_location_permission_request"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textColor="#ffffff"
+        app:layout_constraintBottom_toTopOf="@+id/deny_permission_request"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/mainMessageTextView" />
+
+    <Button
+        android:id="@+id/deny_permission_request"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="8dp"
+        android:layout_marginStart="16dp"
+        android:background="@android:color/transparent"
+        android:onClick="onClickDenyPermissionRequest"
+        android:stateListAnimator="@null"
+        android:text="@string/no_thanks_activity_location_permission_request"
+        android:textColor="#ffffff"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+    <Button
+        android:id="@+id/approve_permission_request"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="8dp"
+        android:layout_marginEnd="16dp"
+        android:background="@android:color/transparent"
+        android:onClick="onClickApprovePermissionRequest"
+        android:stateListAnimator="@null"
+        android:text="@string/continue_activity_location_permission_request"
+        android:textColor="#ffffff"
+        android:textStyle="bold"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/activity_main.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..0dd4bc1
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/activity_main.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 Google Inc. All rights reserved.
+  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.
+  -->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/coordinatorLayout"
+    tools:context=".MainActivity">
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/recycler_view"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_marginBottom="8dp"
+        android:layout_marginEnd="16dp"
+        android:layout_marginStart="16dp"
+        android:layout_marginTop="8dp"
+        android:scrollbars="vertical"
+        app:layout_constraintBottom_toTopOf="@+id/access_point_summary_text_view"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.69"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="1.0" />
+
+    <TextView
+        android:id="@+id/access_point_summary_text_view"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="8dp"
+        android:layout_marginEnd="16dp"
+        android:layout_marginStart="16dp"
+        android:layout_marginTop="8dp"
+        android:text="@string/introduction_text"
+        android:textAlignment="center"
+        android:visibility="visible"
+        app:layout_constraintBottom_toTopOf="@+id/scan_wifi_button"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.0"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.991" />
+
+    <Button
+        android:id="@+id/scan_wifi_button"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="8dp"
+        android:layout_marginEnd="16dp"
+        android:layout_marginStart="16dp"
+        android:onClick="onClickFindDistancesToAccessPoints"
+        android:text="@string/scan_wifi_button_label"
+        android:visibility="visible"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/recycler_row_header.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/recycler_row_header.xml
new file mode 100644
index 0000000..462cdee
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/recycler_row_header.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2018 Google Inc.
+  ~
+  ~ 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.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:paddingTop="@dimen/recycler_row_padding"
+    android:paddingBottom="@dimen/recycler_row_padding"
+    android:orientation="horizontal">
+
+    <TextView
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:gravity="center_vertical"
+        android:textAlignment="center"
+        android:textSize="@dimen/recycler_row_header_text_size"
+        android:text="@string/recycler_row_header_label_ssid"
+        android:id="@+id/ssid_text_view"/>
+
+    <TextView
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:gravity="center_vertical"
+        android:textAlignment="center"
+        android:text="@string/recycler_row_header_label_bssid"
+        android:textSize="@dimen/recycler_row_header_text_size"
+        android:id="@+id/bssid_text_view"/>
+</LinearLayout>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/recycler_row_item.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/recycler_row_item.xml
new file mode 100644
index 0000000..499e9c0
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/layout/recycler_row_item.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2018 Google Inc.
+  ~
+  ~ 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.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:paddingTop="@dimen/recycler_row_padding"
+    android:paddingBottom="@dimen/recycler_row_padding"
+    android:orientation="horizontal"
+    android:clickable="true">
+
+    <TextView
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:gravity="center_vertical"
+        android:textAlignment="center"
+        android:textSize="@dimen/recycler_row_item_text_size"
+        android:id="@+id/ssid_text_view"/>
+
+    <TextView
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:gravity="center_vertical"
+        android:textAlignment="center"
+        android:textSize="@dimen/recycler_row_item_text_size"
+        android:id="@+id/bssid_text_view"/>
+</LinearLayout>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6568fb6
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 Google Inc. All rights reserved.
+  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.
+  -->
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6568fb6
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 Google Inc. All rights reserved.
+  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.
+  -->
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-hdpi/ic_launcher.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a2f5908
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-hdpi/ic_launcher_round.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..1b52399
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-hdpi/ic_launcher_round.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-mdpi/ic_launcher.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..ff10afd
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-mdpi/ic_launcher_round.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..115a4c7
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-mdpi/ic_launcher_round.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xhdpi/ic_launcher.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..dcd3cd8
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..459ca60
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xxhdpi/ic_launcher.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..8ca12fe
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..8e19b41
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b824ebd
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..4c19a13
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceLarge</item>
+        <item name="android:lineSpacingMultiplier">1.2</item>
+        <item name="android:shadowDy">-6.5</item>
+    </style>
+
+</resources>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-v11/template-styles.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-v11/template-styles.xml
new file mode 100644
index 0000000..8c1ea66
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-v21/base-colors.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-v21/base-colors.xml
new file mode 100644
index 0000000..8b6ec3f
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-v21/base-colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+
+</resources>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-v21/base-template-styles.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-v21/base-template-styles.xml
new file mode 100644
index 0000000..c778e4f
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values-v21/base-template-styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+    <!-- Activity themes -->
+    <style name="Theme.Base" parent="android:Theme.Material.Light">
+    </style>
+
+</resources>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/base-strings.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..f837483
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/base-strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+    <string name="app_name">WifiRttScan</string>
+    <string name="intro_message">
+        <![CDATA[
+        
+
+Sample demonstrates best practices for using WifiRTT APIs in Android. Also, this is a a useful
+application for testing Wifi-RTT enabled phones and access points and validating the estimated
+distance is close to the actual distance between them.
+
+        
+        ]]>
+    </string>
+</resources>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/colors.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/colors.xml
new file mode 100644
index 0000000..48f51a2
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 Google Inc. All rights reserved.
+  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.
+  -->
+<resources>
+    <color name="colorPrimary">#3F51B5</color>
+    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorSecondary">#9fa8da</color>
+    <color name="colorAccent">#FF4081</color>
+</resources>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/dimens.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..990b85d
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/dimens.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 Google Inc. All rights reserved.
+  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.
+  -->
+<resources>
+    <dimen name="recycler_row_padding">5dp</dimen>
+    <dimen name="recycler_row_header_text_size">30sp</dimen>
+    <dimen name="recycler_row_item_text_size">20sp</dimen>
+
+    <dimen name="activity_access_point_ranging_request_header_text_size">24sp</dimen>
+    <dimen name="activity_access_point_ranging_request_item_text_size">20sp</dimen>
+    <dimen name="activity_access_point_ranging_request_margin_end">16dp</dimen>
+    <dimen name="activity_access_point_ranging_request_margin_start">16dp</dimen>
+    <dimen name="activity_access_point_ranging_request_margin_top">8dp</dimen>
+    <dimen name="activity_access_point_ranging_request_margin_top_title">16dp</dimen>
+    <dimen name="activity_access_point_ranging_request_margin_top_divider">16dp</dimen>
+    <dimen name="activity_access_point_ranging_request_divider_height">1dp</dimen>
+    <dimen name="activity_access_point_ranging_request_edit_view_height">44dp</dimen>
+    <dimen name="activity_access_point_ranging_request_edit_view_width">116dp</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/strings.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/strings.xml
new file mode 100644
index 0000000..f7d637f
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 Google Inc. All rights reserved.
+  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.
+-->
+<resources>
+    <string name="action_settings">Settings</string>
+
+    <string name="title_activity_location_permission_request">Location Permission Required</string>
+    <string name="main_message_activity_location_permission_request">See distances to access points with Wifi RTT (permission required).</string>
+    <string name="details_message_activity_location_permission_request">This app needs access to your phone\'s location to show the distances between this device and Wifi RTT enabled access points.</string>
+    <string name="no_thanks_activity_location_permission_request">No Thanks</string>
+    <string name="continue_activity_location_permission_request">Continue</string>
+
+    <string name="recycler_row_header_label_ssid">SSID</string>
+    <string name="recycler_row_header_label_bssid">BSSID</string>
+    <string name="retrieving_access_points">Retrieving Access Points&#8230;</string>
+    <string name="scan_wifi_button_label">Scan WiFi</string>
+    <string name="introduction_text">Click the button below to scan access points.</string>
+
+    <!-- Strings for AccessPointRangingResultsActivity. -->
+    <string name="title_activity_access_point_ranging_results">Access Point Ranging Results</string>
+    <string name="activity_access_point_ranging_results_requesting_default">Requesting&#8230;</string>
+    <string name="range_label_activity_access_point_ranging_results">Range (m):</string>
+    <string name="range_mean_label_activity_access_point_ranging_results">Range-mean (m):</string>
+    <string name="range_sd_label_activity_access_point_ranging_results">RangeSD (m):</string>
+    <string name="range_sd_mean_activity_access_point_ranging_results">RangeSD-mean (m):</string>
+    <string name="rssi_label_activity_access_point_ranging_results">RSSI (dBm):</string>
+    <string name="successes_in_burst_label_activity_access_point_ranging_results">Successes in burst:</string>
+    <string name="success_ratio_label_activity_access_point_ranging_results">Success Ratio:</string>
+
+    <string name="stats_window_size_label_activity_access_point_ranging_results">Stats window size:</string>
+    <string name="ranging_period_label_activity_access_point_ranging_results">Ranging period (ms):</string>
+
+    <string name="reset_label_activity_access_point_ranging_results">Reset Ranging Requests</string>
+    <string name="number_of_requests_label_activity_access_point_ranging_results">Number of requests:</string>
+    <string name="mac_mismatch_message_activity_access_point_ranging_results">Callback MAC address doesn\'t match original request MAC address.</string>
+
+</resources>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/styles.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/styles.xml
new file mode 100644
index 0000000..2d82d15
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/styles.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2018 Google Inc. All rights reserved.
+  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.
+-->
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="CustomAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorSecondary">@color/colorSecondary</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
+    <style name="CustomAppTheme.NoActionBar">
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
+    <style name="CustomAppTheme.AppBarOverlay"
+        parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
+
+    <style name="CustomAppTheme.PopupOverlay"
+        parent="ThemeOverlay.AppCompat.Light" />
+
+</resources>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/template-dimens.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+    <dimen name="margin_tiny">4dp</dimen>
+    <dimen name="margin_small">8dp</dimen>
+    <dimen name="margin_medium">16dp</dimen>
+    <dimen name="margin_large">32dp</dimen>
+    <dimen name="margin_huge">64dp</dimen>
+
+    <!-- Semantic definitions -->
+
+    <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+    <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/template-styles.xml b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..6e7d593
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/Application/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+  Copyright 2013 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.
+  -->
+
+<resources>
+
+    <!-- Activity themes -->
+
+    <style name="Theme.Base" parent="android:Theme.Light" />
+
+    <style name="Theme.Sample" parent="Theme.Base" />
+
+    <style name="AppTheme" parent="Theme.Sample" />
+    <!-- Widget styling -->
+
+    <style name="Widget" />
+
+    <style name="Widget.SampleMessage">
+        <item name="android:textAppearance">?android:textAppearanceMedium</item>
+        <item name="android:lineSpacingMultiplier">1.1</item>
+    </style>
+
+    <style name="Widget.SampleMessageTile">
+        <item name="android:background">@drawable/tile</item>
+        <item name="android:shadowColor">#7F000000</item>
+        <item name="android:shadowDy">-3.5</item>
+        <item name="android:shadowRadius">2</item>
+    </style>
+
+</resources>
diff --git a/prebuilts/gradle/WifiRttScan/CONTRIBUTING.md b/prebuilts/gradle/WifiRttScan/CONTRIBUTING.md
new file mode 100644
index 0000000..faa8b5c
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/CONTRIBUTING.md
@@ -0,0 +1,35 @@
+# How to become a contributor and submit your own code
+
+## Contributor License Agreements
+
+We'd love to accept your sample apps and patches! Before we can take them, we
+have to jump a couple of legal hurdles.
+
+Please fill out either the individual or corporate Contributor License Agreement (CLA).
+
+  * If you are an individual writing original source code and you're sure you
+    own the intellectual property, then you'll need to sign an [individual CLA]
+    (https://cla.developers.google.com).
+  * If you work for a company that wants to allow you to contribute your work,
+    then you'll need to sign a [corporate CLA]
+    (https://cla.developers.google.com).
+
+Follow either of the two links above to access the appropriate CLA and
+instructions for how to sign and return it. Once we receive it, we'll be able to
+accept your pull requests.
+
+## Contributing A Patch
+
+1. Submit an issue describing your proposed change to the repo in question.
+1. The repo owner will respond to your issue promptly.
+1. If your proposed change is accepted, and you haven't already done so, sign a
+   Contributor License Agreement (see details above).
+1. Fork the desired repo, develop and test your code changes.
+1. Ensure that your code adheres to the existing style in the sample to which
+   you are contributing. Refer to the
+   [Android Code Style Guide]
+   (https://source.android.com/source/code-style.html) for the
+   recommended coding standards for this organization.
+1. Ensure that your code has an appropriate set of unit tests which all pass.
+1. Submit a pull request.
+
diff --git a/prebuilts/gradle/WifiRttScan/LICENSE b/prebuilts/gradle/WifiRttScan/LICENSE
new file mode 100644
index 0000000..d5cf8f3
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/LICENSE
@@ -0,0 +1,203 @@
+Apache License
+--------------
+
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   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.
diff --git a/prebuilts/gradle/WifiRttScan/README.md b/prebuilts/gradle/WifiRttScan/README.md
new file mode 100644
index 0000000..64a3c33
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/README.md
@@ -0,0 +1,58 @@
+
+Android WifiRttScan Sample
+===================================
+
+Sample demonstrates best practices for using WifiRTT APIs in Android. Also, this is a a useful
+application for testing Wifi-RTT enabled phones and access points and validating the estimated
+distance is close to the actual distance between them.
+
+Introduction
+------------
+
+Steps for trying out the sample:
+* Compile and install the mobile app onto your mobile device (for mobile scenario).
+
+This sample demonstrates best practices for using the WifiRtt APIs in Android. The main activity
+lists all access points that are WifiRtt enabled using the [WifiManager][1]. By clicking on one of
+the access points, another activity will launch and initiate [RangingRequest][2] via the
+[WifiRttManager][3]. The activity will display many of the details returned from the access point
+including the distance between the access point and the phone.
+
+[1]: https://developer.android.com/reference/android/net/wifi/WifiManager
+[2]: https://developer.android.com/reference/android/net/wifi/rtt/RangingRequest
+[3]: https://developer.android.com/reference/android/net/wifi/rtt/WifiRttManager
+
+Pre-requisites
+--------------
+
+- Android SDK 28
+- Android Build Tools v27.0.3
+- Android Support Repository
+
+Screenshots
+-------------
+
+<img src="screenshots/main1.png" height="400" alt="Screenshot"/> <img src="screenshots/main2.png" height="400" alt="Screenshot"/> <img src="screenshots/main3.png" height="400" alt="Screenshot"/> 
+
+Getting Started
+---------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+Support
+-------
+
+- Google+ Community: https://plus.google.com/communities/105153134372062985968
+- Stack Overflow: http://stackoverflow.com/questions/tagged/android
+
+If you've found an error in this sample, please file an issue:
+https://github.com/googlesamples/android-WifiRttScan
+
+Patches are encouraged, and may be submitted by forking this project and
+submitting a pull request through GitHub. Please see CONTRIBUTING.md for more details.
+
+License
+-------
+Licensed under an Apache 2.0 license. See LICENSE file for details.
+
diff --git a/prebuilts/gradle/WifiRttScan/build.gradle b/prebuilts/gradle/WifiRttScan/build.gradle
new file mode 100644
index 0000000..08744c6
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/build.gradle
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2018 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/WifiRttScan/gradle.properties b/prebuilts/gradle/WifiRttScan/gradle.properties
new file mode 100644
index 0000000..94f8472
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/gradle.properties
@@ -0,0 +1,22 @@
+
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Settings specified in this file will override any Gradle settings
+# configured through the IDE.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/prebuilts/gradle/WifiRttScan/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/WifiRttScan/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/WifiRttScan/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..562d1fa
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jul 27 17:47:47 PDT 2018
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-rc-1-all.zip
diff --git a/prebuilts/gradle/WifiRttScan/gradlew b/prebuilts/gradle/WifiRttScan/gradlew
new file mode 100644
index 0000000..b3fa6f2
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/gradlew
@@ -0,0 +1,178 @@
+#!/usr/bin/env bash
+
+# Copyright 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.
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/WifiRttScan/gradlew.bat b/prebuilts/gradle/WifiRttScan/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off

+@rem ##########################################################################

+@rem

+@rem  Gradle startup script for Windows

+@rem

+@rem ##########################################################################

+

+@rem Set local scope for the variables with windows NT shell

+if "%OS%"=="Windows_NT" setlocal

+

+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

+set DEFAULT_JVM_OPTS=

+

+set DIRNAME=%~dp0

+if "%DIRNAME%" == "" set DIRNAME=.

+set APP_BASE_NAME=%~n0

+set APP_HOME=%DIRNAME%

+

+@rem Find java.exe

+if defined JAVA_HOME goto findJavaFromJavaHome

+

+set JAVA_EXE=java.exe

+%JAVA_EXE% -version >NUL 2>&1

+if "%ERRORLEVEL%" == "0" goto init

+

+echo.

+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:findJavaFromJavaHome

+set JAVA_HOME=%JAVA_HOME:"=%

+set JAVA_EXE=%JAVA_HOME%/bin/java.exe

+

+if exist "%JAVA_EXE%" goto init

+

+echo.

+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:init

+@rem Get command-line arguments, handling Windowz variants

+

+if not "%OS%" == "Windows_NT" goto win9xME_args

+if "%@eval[2+2]" == "4" goto 4NT_args

+

+:win9xME_args

+@rem Slurp the command line arguments.

+set CMD_LINE_ARGS=

+set _SKIP=2

+

+:win9xME_args_slurp

+if "x%~1" == "x" goto execute

+

+set CMD_LINE_ARGS=%*

+goto execute

+

+:4NT_args

+@rem Get arguments from the 4NT Shell from JP Software

+set CMD_LINE_ARGS=%$

+

+:execute

+@rem Setup the command line

+

+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

+

+@rem Execute Gradle

+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

+

+:end

+@rem End local scope for the variables with windows NT shell

+if "%ERRORLEVEL%"=="0" goto mainEnd

+

+:fail

+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

+rem the _cmd.exe /c_ return code!

+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

+exit /b 1

+

+:mainEnd

+if "%OS%"=="Windows_NT" endlocal

+

+:omega

diff --git a/prebuilts/gradle/WifiRttScan/screenshots/main1.png b/prebuilts/gradle/WifiRttScan/screenshots/main1.png
new file mode 100644
index 0000000..a4b594e
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/screenshots/main1.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/screenshots/main2.png b/prebuilts/gradle/WifiRttScan/screenshots/main2.png
new file mode 100644
index 0000000..c838021
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/screenshots/main2.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/screenshots/main3.png b/prebuilts/gradle/WifiRttScan/screenshots/main3.png
new file mode 100644
index 0000000..f364782
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/screenshots/main3.png
Binary files differ
diff --git a/prebuilts/gradle/WifiRttScan/settings.gradle b/prebuilts/gradle/WifiRttScan/settings.gradle
new file mode 100644
index 0000000..7c9c961
--- /dev/null
+++ b/prebuilts/gradle/WifiRttScan/settings.gradle
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2018 Google Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+include 'Application'