diff options
author | Jeremy Walker <jewalker@google.com> | 2018-07-27 08:17:22 -0700 |
---|---|---|
committer | Jeremy Walker <jewalker@google.com> | 2018-07-27 17:48:20 -0700 |
commit | e1364aad5e9b008a6d99336e533da1e0a0a2622c (patch) | |
tree | 11caf01250c02c817ba9c6820c11aba7bc58b2ca /connectivity/wifirtt/WifiRttScan | |
parent | 6d7132906d2a9a6eb7072c5486b2748f69c5eb8b (diff) | |
download | android-e1364aad5e9b008a6d99336e533da1e0a0a2622c.tar.gz |
Adds interval and all other details for WifiRTT scanning.
Bug: 111830148
Test: Manually tested.
Change-Id: I8ee53df3cb08e151713f0be98e5778a04e1c2f7b
Diffstat (limited to 'connectivity/wifirtt/WifiRttScan')
6 files changed, 323 insertions, 58 deletions
diff --git a/connectivity/wifirtt/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/AccessPointRangingResultsActivity.java b/connectivity/wifirtt/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/AccessPointRangingResultsActivity.java index ca147740..cced739a 100644 --- a/connectivity/wifirtt/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/AccessPointRangingResultsActivity.java +++ b/connectivity/wifirtt/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/AccessPointRangingResultsActivity.java @@ -15,72 +15,320 @@ */ 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 android.support.annotation.NonNull; +import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; import android.widget.EditText; import android.widget.TextView; +import android.widget.Toast; -/** Displays ranging information about a particular access point chosen by the user. */ +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 STATISTIC_WINDOW_SIZE_DEFAULT = 50; - private static final int RANGING_PERIOD_MILLISECONDS_DEFAULT = 1000; - - private ScanResult mScanResult; + 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 mRange; - private TextView mRangeMean; - private TextView mRangeSD; - private TextView mRangeSDMean; - private TextView mRssi; - private TextView mSuccessesInBurst; - private TextView mSuccessRatio; + 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; - private EditText mStatsWindowSize; - private EditText mRangingPeriod; + // 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; - private int mStatisticWindowSize; - private int mRangingPeriodMilliseconds; + // 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); - mRange = findViewById(R.id.range_value); - mRangeMean = findViewById(R.id.range_mean_value); - mRangeSD = findViewById(R.id.range_sd_value); - mRangeSDMean = findViewById(R.id.range_sd_mean_value); - mRssi = findViewById(R.id.rssi_value); - mSuccessesInBurst = findViewById(R.id.successes_in_burst_value); - mSuccessRatio = findViewById(R.id.success_ratio_value); + 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); - mStatsWindowSize = findViewById(R.id.stats_window_size_edit_value); - mStatisticWindowSize = STATISTIC_WINDOW_SIZE_DEFAULT; - mStatsWindowSize.setText(mStatisticWindowSize + ""); + mSampleSizeEditText = findViewById(R.id.stats_window_size_edit_value); + mSampleSizeEditText.setText(SAMPLE_SIZE_DEFAULT + ""); - mRangingPeriod = findViewById(R.id.ranging_period_edit_value); - mRangingPeriodMilliseconds = RANGING_PERIOD_MILLISECONDS_DEFAULT; - mRangingPeriod.setText(mRangingPeriodMilliseconds + ""); + 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); - // TODO (jewalker): Implement Ranging Request. + 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/connectivity/wifirtt/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MainActivity.java b/connectivity/wifirtt/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MainActivity.java index 44be36d8..53127826 100644 --- a/connectivity/wifirtt/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MainActivity.java +++ b/connectivity/wifirtt/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MainActivity.java @@ -168,10 +168,11 @@ public class MainActivity extends AppCompatActivity implements ScanResultClickLi mAdapter.swapData(mAccessPointsSupporting80211mc); - logToUi(scanResults.size() + - " APs discovered, " + - mAccessPointsSupporting80211mc.size() + - " RTT capable."); + logToUi( + scanResults.size() + + " APs discovered, " + + mAccessPointsSupporting80211mc.size() + + " RTT capable."); } else { // TODO (jewalker): Add Snackbar regarding permissions diff --git a/connectivity/wifirtt/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MyAdapter.java b/connectivity/wifirtt/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MyAdapter.java index 2427f908..8ba80973 100644 --- a/connectivity/wifirtt/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MyAdapter.java +++ b/connectivity/wifirtt/WifiRttScan/Application/src/main/java/com/example/android/wifirttscan/MyAdapter.java @@ -39,9 +39,7 @@ public class MyAdapter extends RecyclerView.Adapter<ViewHolder> { private List<ScanResult> mWifiAccessPointsWithRtt; - public MyAdapter( - List<ScanResult> list, - ScanResultClickListener scanResultClickListener) { + public MyAdapter(List<ScanResult> list, ScanResultClickListener scanResultClickListener) { mWifiAccessPointsWithRtt = list; sScanResultClickListener = scanResultClickListener; } @@ -65,8 +63,7 @@ public class MyAdapter extends RecyclerView.Adapter<ViewHolder> { @Override public void onClick(View view) { - sScanResultClickListener.onScanResultItemClick( - getItem(getAdapterPosition())); + sScanResultClickListener.onScanResultItemClick(getItem(getAdapterPosition())); } } diff --git a/connectivity/wifirtt/WifiRttScan/Application/src/main/res/layout/activity_access_point_ranging_results.xml b/connectivity/wifirtt/WifiRttScan/Application/src/main/res/layout/activity_access_point_ranging_results.xml index 70abd392..b74c779a 100644 --- a/connectivity/wifirtt/WifiRttScan/Application/src/main/res/layout/activity_access_point_ranging_results.xml +++ b/connectivity/wifirtt/WifiRttScan/Application/src/main/res/layout/activity_access_point_ranging_results.xml @@ -240,18 +240,44 @@ 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_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: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/success_ratio_value" /> + app:layout_constraintTop_toBottomOf="@+id/number_of_requests_value" /> <TextView android:id="@+id/stats_window_size_label" @@ -273,6 +299,7 @@ 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" @@ -300,6 +327,7 @@ 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" @@ -309,13 +337,15 @@ <Button android:id="@+id/reset_button" - android:layout_width="91dp" + 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" /> + </android.support.constraint.ConstraintLayout> diff --git a/connectivity/wifirtt/WifiRttScan/Application/src/main/res/values/strings.xml b/connectivity/wifirtt/WifiRttScan/Application/src/main/res/values/strings.xml index 1bfda3e7..f7d637fe 100644 --- a/connectivity/wifirtt/WifiRttScan/Application/src/main/res/values/strings.xml +++ b/connectivity/wifirtt/WifiRttScan/Application/src/main/res/values/strings.xml @@ -40,6 +40,8 @@ <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</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/connectivity/wifirtt/WifiRttScan/gradle/wrapper/gradle-wrapper.properties b/connectivity/wifirtt/WifiRttScan/gradle/wrapper/gradle-wrapper.properties index fdc97096..562d1fa4 100644 --- a/connectivity/wifirtt/WifiRttScan/gradle/wrapper/gradle-wrapper.properties +++ b/connectivity/wifirtt/WifiRttScan/gradle/wrapper/gradle-wrapper.properties @@ -1,19 +1,6 @@ -# 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. -#Wed Apr 10 15:27:10 PDT 2013 +#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.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-rc-1-all.zip |