aboutsummaryrefslogtreecommitdiff
path: root/android/WALT/app/src/main/java/org/chromium/latency/walt
diff options
context:
space:
mode:
Diffstat (limited to 'android/WALT/app/src/main/java/org/chromium/latency/walt')
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/AboutFragment.java6
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/AccelerometerFragment.java379
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/AudioFragment.java9
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/AutoRunFragment.java5
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/BaseUsbConnection.java8
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/CrashLogActivity.java3
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/DiagnosticsFragment.java3
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/DragLatencyFragment.java7
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/FastPathSurfaceView.java3
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/FrontPageFragment.java3
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/LogFragment.java9
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/LogUploader.java3
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/MainActivity.java50
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/MidiFragment.java3
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/NumberPickerPreference.java22
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/ScreenResponseFragment.java15
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/SettingsFragment.java29
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/SimpleLogger.java4
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/TapLatencyFragment.java7
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/TraceLogger.java16
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/UsMotionEvent.java9
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/Utils.java37
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/WaltDevice.java19
-rw-r--r--android/WALT/app/src/main/java/org/chromium/latency/walt/programmer/FirmwareImage.java8
24 files changed, 563 insertions, 94 deletions
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/AboutFragment.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/AboutFragment.java
index 08b4e4f..2dce815 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/AboutFragment.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/AboutFragment.java
@@ -19,11 +19,13 @@ package org.chromium.latency.walt;
import android.os.Build;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import java.util.Locale;
+
+import androidx.fragment.app.Fragment;
/**
@@ -46,7 +48,7 @@ public class AboutFragment extends Fragment {
public void onResume() {
super.onResume();
TextView textView = (TextView) getActivity().findViewById(R.id.txt_build_info);
- String text = String.format("WALT v%s (versionCode=%d)\n",
+ String text = String.format(Locale.US, "WALT v%s (versionCode=%d)\n",
BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE);
text += "WALT protocol version: " + WaltDevice.PROTOCOL_VERSION + "\n";
text += "Android Build ID: " + Build.DISPLAY + "\n";
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/AccelerometerFragment.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/AccelerometerFragment.java
new file mode 100644
index 0000000..4f39547
--- /dev/null
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/AccelerometerFragment.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.chromium.latency.walt;
+
+import static org.chromium.latency.walt.Utils.argmax;
+import static org.chromium.latency.walt.Utils.interp;
+import static org.chromium.latency.walt.Utils.max;
+import static org.chromium.latency.walt.Utils.mean;
+import static org.chromium.latency.walt.Utils.min;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.text.method.ScrollingMovementMethod;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.fragment.app.Fragment;
+
+import com.github.mikephil.charting.charts.ScatterChart;
+import com.github.mikephil.charting.components.Description;
+import com.github.mikephil.charting.data.Entry;
+import com.github.mikephil.charting.data.ScatterData;
+import com.github.mikephil.charting.data.ScatterDataSet;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+public class AccelerometerFragment extends Fragment implements
+ View.OnClickListener, SensorEventListener {
+
+ private static final int MAX_TEST_LENGTH_MS = 10000;
+ private SimpleLogger logger;
+ private WaltDevice waltDevice;
+ private TextView logTextView;
+ private View startButton;
+ private ScatterChart latencyChart;
+ private View latencyChartLayout;
+ private StringBuilder accelerometerData;
+ private List<AccelerometerEvent> phoneAccelerometerData = new ArrayList<>();
+ private Handler handler = new Handler();
+ private SensorManager sensorManager;
+ private Sensor accelerometer;
+ private double realTimeOffsetMs;
+ private boolean isTestRunning = false;
+
+ Runnable finishAccelerometer = new Runnable() {
+ @Override
+ public void run() {
+ isTestRunning = false;
+ waltDevice.stopListener();
+ waltDevice.clearTriggerHandler();
+ calculateAndDrawLatencyChart(accelerometerData.toString());
+ startButton.setEnabled(true);
+ accelerometerData = new StringBuilder();
+ LogUploader.uploadIfAutoEnabled(getContext());
+ }
+ };
+
+ private BroadcastReceiver logReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String msg = intent.getStringExtra("message");
+ AccelerometerFragment.this.appendLogText(msg);
+ }
+ };
+
+ private WaltDevice.TriggerHandler triggerHandler = new WaltDevice.TriggerHandler() {
+ @Override
+ public void onReceive(WaltDevice.TriggerMessage tmsg) {
+ logger.log("ERROR: Accelerometer trigger got a trigger message, " +
+ "this should never happen.");
+ }
+
+ @Override
+ public void onReceiveRaw(String s) {
+ if (s.trim().equals("end")) {
+ // Remove the delayed callback and run it now
+ handler.removeCallbacks(finishAccelerometer);
+ handler.post(finishAccelerometer);
+ } else {
+ accelerometerData.append(s);
+ }
+ }
+ };
+
+ Runnable startAccelerometer = new Runnable() {
+ @Override
+ public void run() {
+ waltDevice.setTriggerHandler(triggerHandler);
+ try {
+ waltDevice.command(WaltDevice.CMD_ACCELEROMETER);
+ } catch (IOException e) {
+ logger.log("Error sending command CMD_ACCELEROMETER: " + e.getMessage());
+ startButton.setEnabled(true);
+ return;
+ }
+
+ logger.log("=== Accelerometer Test ===\n");
+ isTestRunning = true;
+ handler.postDelayed(finishAccelerometer, MAX_TEST_LENGTH_MS);
+ }
+ };
+
+ public AccelerometerFragment() {
+ // Required empty public constructor
+ }
+
+ static List<Entry> getEntriesFromString(final String latencyString) {
+ List<Entry> entries = new ArrayList<>();
+ // "o" marks the start of the accelerometer data
+ int startIndex = latencyString.indexOf("o") + 1;
+
+ String[] brightnessStrings =
+ latencyString.substring(startIndex).trim().split("\n");
+ for (String str : brightnessStrings) {
+ String[] arr = str.split(" ");
+ final float timestampMs = Integer.parseInt(arr[0]) / 1000f;
+ final float value = Integer.parseInt(arr[1]);
+ entries.add(new Entry(timestampMs, value));
+ }
+ return entries;
+ }
+
+ static List<Entry> smoothEntries(List<Entry> entries, int windowSize) {
+ List<Entry> smoothEntries = new ArrayList<>();
+ for (int i = windowSize; i < entries.size() - windowSize; i++) {
+ final float time = entries.get(i).getX();
+ float avg = 0;
+ for (int j = i - windowSize; j <= i + windowSize; j++) {
+ avg += entries.get(j).getY() / (2 * windowSize + 1);
+ }
+ smoothEntries.add(new Entry(time, avg));
+ }
+ return smoothEntries;
+ }
+
+ static double[] findShifts(List<Entry> phoneEntries, List<Entry> waltEntries) {
+ double[] phoneTimes = new double[phoneEntries.size()];
+ double[] phoneValues = new double[phoneEntries.size()];
+ double[] waltTimes = new double[waltEntries.size()];
+ double[] waltValues = new double[waltEntries.size()];
+
+ for (int i = 0; i < phoneTimes.length; i++) {
+ phoneTimes[i] = phoneEntries.get(i).getX();
+ phoneValues[i] = phoneEntries.get(i).getY();
+ }
+
+ for (int i = 0; i < waltTimes.length; i++) {
+ waltTimes[i] = waltEntries.get(i).getX();
+ waltValues[i] = waltEntries.get(i).getY();
+ }
+
+ double[] shiftCorrelations = new double[401];
+ for (int i = 0; i < shiftCorrelations.length; i++) {
+ double shift = i / 10.;
+ final double[] shiftedPhoneTimes = new double[phoneTimes.length];
+ for (int j = 0; j < phoneTimes.length; j++) {
+ shiftedPhoneTimes[j] = phoneTimes[j] - shift;
+ }
+ final double[] interpolatedValues = interp(shiftedPhoneTimes, waltTimes, waltValues);
+ double sum = 0;
+ for (int j = 0; j < shiftedPhoneTimes.length; j++) {
+ // Calculate square dot product of phone and walt values
+ sum += Math.pow(phoneValues[j] * interpolatedValues[j], 2);
+ }
+ shiftCorrelations[i] = sum;
+ }
+ return shiftCorrelations;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ logger = SimpleLogger.getInstance(getContext());
+ waltDevice = WaltDevice.getInstance(getContext());
+
+ // Inflate the layout for this fragment
+ final View view = inflater.inflate(R.layout.fragment_accelerometer, container, false);
+ logTextView = (TextView) view.findViewById(R.id.txt_log);
+ startButton = view.findViewById(R.id.button_start);
+ latencyChart = (ScatterChart) view.findViewById(R.id.latency_chart);
+ latencyChartLayout = view.findViewById(R.id.latency_chart_layout);
+ logTextView.setMovementMethod(new ScrollingMovementMethod());
+ view.findViewById(R.id.button_close_chart).setOnClickListener(this);
+ sensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
+ accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ if (accelerometer == null) {
+ logger.log("ERROR! Accelerometer sensor not found");
+ }
+ return view;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ logTextView.setText(logger.getLogText());
+ logger.registerReceiver(logReceiver);
+ startButton.setOnClickListener(this);
+ sensorManager.registerListener(
+ AccelerometerFragment.this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
+ }
+
+ @Override
+ public void onPause() {
+ logger.unregisterReceiver(logReceiver);
+ sensorManager.unregisterListener(AccelerometerFragment.this, accelerometer);
+ super.onPause();
+ }
+
+ public void appendLogText(String msg) {
+ logTextView.append(msg + "\n");
+ }
+
+ void startMeasurement() {
+ logger.log("Starting accelerometer latency measurement");
+ try {
+ accelerometerData = new StringBuilder();
+ phoneAccelerometerData.clear();
+ waltDevice.syncClock();
+ waltDevice.startListener();
+ realTimeOffsetMs =
+ SystemClock.elapsedRealtimeNanos() / 1e6 - waltDevice.clock.micros() / 1e3;
+ } catch (IOException e) {
+ logger.log("Error syncing clocks: " + e.getMessage());
+ startButton.setEnabled(true);
+ return;
+ }
+ Toast.makeText(getContext(), "Start shaking the phone and WALT!", Toast.LENGTH_LONG).show();
+ handler.postDelayed(startAccelerometer, 500);
+ }
+
+ /**
+ * Handler for all the button clicks on this screen.
+ */
+ @Override
+ public void onClick(View v) {
+ if (v.getId() == R.id.button_start) {
+ latencyChartLayout.setVisibility(View.GONE);
+ startButton.setEnabled(false);
+ startMeasurement();
+ return;
+ }
+
+ if (v.getId() == R.id.button_close_chart) {
+ latencyChartLayout.setVisibility(View.GONE);
+ }
+ }
+
+ private void calculateAndDrawLatencyChart(final String latencyString) {
+ List<Entry> phoneEntries = new ArrayList<>();
+ List<Entry> waltEntries = getEntriesFromString(latencyString);
+ List<Entry> waltSmoothEntries = smoothEntries(waltEntries, 4);
+
+ for (AccelerometerEvent e : phoneAccelerometerData) {
+ phoneEntries.add(new Entry(e.callbackTimeMs, e.value));
+ }
+
+ while (phoneEntries.get(0).getX() < waltSmoothEntries.get(0).getX()) {
+ // This event is earlier than any walt event, so discard it
+ phoneEntries.remove(0);
+ }
+
+ while (phoneEntries.get(phoneEntries.size() - 1).getX() >
+ waltSmoothEntries.get(waltSmoothEntries.size() - 1).getX()) {
+ // This event is later than any walt event, so discard it
+ phoneEntries.remove(phoneEntries.size() - 1);
+ }
+
+ // Adjust waltEntries so min and max is the same as phoneEntries
+ float phoneMean = mean(phoneEntries);
+ float phoneMax = max(phoneEntries);
+ float phoneMin = min(phoneEntries);
+ float waltMin = min(waltSmoothEntries);
+ float phoneRange = phoneMax - phoneMin;
+ float waltRange = max(waltSmoothEntries) - waltMin;
+ for (Entry e : waltSmoothEntries) {
+ e.setY((e.getY() - waltMin) * (phoneRange / waltRange) + phoneMin - phoneMean);
+ }
+
+ // Adjust phoneEntries so mean=0
+ for (Entry e : phoneEntries) {
+ e.setY(e.getY() - phoneMean);
+ }
+
+ double[] shifts = findShifts(phoneEntries, waltSmoothEntries);
+ double bestShift = argmax(shifts) / 10d;
+ logger.log(String.format(Locale.US, "Accelerometer latency: %.1fms", bestShift));
+
+ double[] deltasKernelToCallback = new double[phoneAccelerometerData.size()];
+ for (int i = 0; i < deltasKernelToCallback.length; i++) {
+ deltasKernelToCallback[i] = phoneAccelerometerData.get(i).callbackTimeMs -
+ phoneAccelerometerData.get(i).kernelTimeMs;
+ }
+
+ logger.log(String.format(
+ Locale.US, "Mean kernel-to-callback latency: %.1fms", mean(deltasKernelToCallback)));
+
+ List<Entry> phoneEntriesShifted = new ArrayList<>();
+ for (Entry e : phoneEntries) {
+ phoneEntriesShifted.add(new Entry((float) (e.getX() - bestShift), e.getY()));
+ }
+
+ drawLatencyChart(phoneEntriesShifted, waltSmoothEntries);
+ }
+
+ private void drawLatencyChart(List<Entry> phoneEntriesShifted, List<Entry> waltEntries) {
+ final ScatterDataSet dataSetWalt =
+ new ScatterDataSet(waltEntries, "WALT Events");
+ dataSetWalt.setColor(Color.BLUE);
+ dataSetWalt.setScatterShape(ScatterChart.ScatterShape.CIRCLE);
+ dataSetWalt.setScatterShapeSize(8f);
+
+ final ScatterDataSet dataSetPhoneShifted =
+ new ScatterDataSet(phoneEntriesShifted, "Phone Events Shifted");
+ dataSetPhoneShifted.setColor(Color.RED);
+ dataSetPhoneShifted.setScatterShapeSize(10f);
+ dataSetPhoneShifted.setScatterShape(ScatterChart.ScatterShape.X);
+
+ final ScatterData scatterData = new ScatterData(dataSetWalt, dataSetPhoneShifted);
+ final Description desc = new Description();
+ desc.setText("");
+ desc.setTextSize(12f);
+ latencyChart.setDescription(desc);
+ latencyChart.setData(scatterData);
+ latencyChart.invalidate();
+ latencyChartLayout.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ if (isTestRunning) {
+ phoneAccelerometerData.add(new AccelerometerEvent(event));
+ }
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ }
+
+ private class AccelerometerEvent {
+ float callbackTimeMs;
+ float kernelTimeMs;
+ float value;
+
+ AccelerometerEvent(SensorEvent event) {
+ callbackTimeMs = waltDevice.clock.micros() / 1e3f;
+ kernelTimeMs = (float) (event.timestamp / 1e6f - realTimeOffsetMs);
+ value = event.values[2];
+ }
+ }
+}
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/AudioFragment.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/AudioFragment.java
index 65452ff..3db3723 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/AudioFragment.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/AudioFragment.java
@@ -16,6 +16,8 @@
package org.chromium.latency.walt;
+import static org.chromium.latency.walt.Utils.getIntPreference;
+
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -24,8 +26,6 @@ import android.content.pm.PackageManager;
import android.graphics.Color;
import android.media.AudioManager;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.content.ContextCompat;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
@@ -34,6 +34,9 @@ import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.Fragment;
+
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.LimitLine;
@@ -45,8 +48,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
-import static org.chromium.latency.walt.Utils.getIntPreference;
-
/**
* A simple {@link Fragment} subclass.
*/
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/AutoRunFragment.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/AutoRunFragment.java
index f2f2a7f..71f5979 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/AutoRunFragment.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/AutoRunFragment.java
@@ -21,14 +21,15 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
-import android.support.annotation.NonNull;
-import android.support.v4.app.Fragment;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/BaseUsbConnection.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/BaseUsbConnection.java
index f0e6c62..4726d12 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/BaseUsbConnection.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/BaseUsbConnection.java
@@ -24,7 +24,8 @@ import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
-import android.support.v4.content.LocalBroadcastManager;
+
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import java.util.HashMap;
import java.util.Locale;
@@ -44,7 +45,7 @@ public abstract class BaseUsbConnection {
protected UsbDeviceConnection usbConnection;
public BaseUsbConnection(Context context) {
- this.context = context;
+ this.context = context.getApplicationContext();
usbManager = (UsbManager) this.context.getSystemService(Context.USB_SERVICE);
logger = SimpleLogger.getInstance(context);
broadcastManager = LocalBroadcastManager.getInstance(context);
@@ -184,7 +185,8 @@ public abstract class BaseUsbConnection {
public UsbDevice findUsbDevice() {
- logger.log(String.format("Looking for TeensyUSB VID=0x%x PID=0x%x", getVid(), getPid()));
+ logger.log(String.format(Locale.US,
+ "Looking for TeensyUSB VID=0x%x PID=0x%x", getVid(), getPid()));
HashMap<String, UsbDevice> deviceHash = usbManager.getDeviceList();
if (deviceHash.size() == 0) {
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/CrashLogActivity.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/CrashLogActivity.java
index 00e80ed..f2ce3d1 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/CrashLogActivity.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/CrashLogActivity.java
@@ -17,10 +17,11 @@
package org.chromium.latency.walt;
import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.widget.TextView;
+import androidx.appcompat.app.AppCompatActivity;
+
/**
* A separate activity to display exception trace on the screen in case of a crash.
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/DiagnosticsFragment.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/DiagnosticsFragment.java
index 65ec3bf..17b0f2f 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/DiagnosticsFragment.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/DiagnosticsFragment.java
@@ -21,13 +21,14 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import androidx.fragment.app.Fragment;
+
/**
* This screen allows to perform different tasks useful for diagnostics.
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/DragLatencyFragment.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/DragLatencyFragment.java
index af03e36..9453c04 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/DragLatencyFragment.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/DragLatencyFragment.java
@@ -16,12 +16,12 @@
package org.chromium.latency.walt;
+import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -29,6 +29,8 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import androidx.fragment.app.Fragment;
+
import com.github.mikephil.charting.charts.ScatterChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.data.Entry;
@@ -67,6 +69,7 @@ public class DragLatencyFragment extends Fragment
}
};
+ @SuppressLint("ClickableViewAccessibility")
private View.OnTouchListener touchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
@@ -143,6 +146,7 @@ public class DragLatencyFragment extends Fragment
/**
* @return true if measurement was successfully started
*/
+ @SuppressLint("ClickableViewAccessibility")
boolean startMeasurement() {
logger.log("Starting drag latency test");
try {
@@ -185,6 +189,7 @@ public class DragLatencyFragment extends Fragment
updateCountsDisplay();
}
+ @SuppressLint("ClickableViewAccessibility")
void finishAndShowStats() {
touchCatcher.stopAnimation();
waltDevice.stopListener();
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/FastPathSurfaceView.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/FastPathSurfaceView.java
index 449627f..0c5ad59 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/FastPathSurfaceView.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/FastPathSurfaceView.java
@@ -22,13 +22,14 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
-import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
+import androidx.annotation.RequiresApi;
+
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/FrontPageFragment.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/FrontPageFragment.java
index cb125e3..84fbbbe 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/FrontPageFragment.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/FrontPageFragment.java
@@ -18,13 +18,14 @@ package org.chromium.latency.walt;
import android.graphics.Color;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.fragment.app.Fragment;
+
/**
* A simple {@link Fragment} subclass.
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/LogFragment.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/LogFragment.java
index 069d032..1e26b32 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/LogFragment.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/LogFragment.java
@@ -17,25 +17,26 @@
package org.chromium.latency.walt;
-import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
+
/**
* A screen that shows the log.
*/
public class LogFragment extends Fragment {
- private Activity activity;
+ private AppCompatActivity activity;
private SimpleLogger logger;
TextView textView;
@@ -56,7 +57,7 @@ public class LogFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- activity = getActivity();
+ activity = (AppCompatActivity) getActivity();
logger = SimpleLogger.getInstance(getContext());
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_log, container, false);
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/LogUploader.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/LogUploader.java
index a73f456..aa10f74 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/LogUploader.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/LogUploader.java
@@ -17,7 +17,8 @@
package org.chromium.latency.walt;
import android.content.Context;
-import android.support.v4.content.AsyncTaskLoader;
+
+import androidx.loader.content.AsyncTaskLoader;
import java.io.BufferedOutputStream;
import java.io.IOException;
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/MainActivity.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/MainActivity.java
index ac1df47..81a637b 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/MainActivity.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/MainActivity.java
@@ -16,6 +16,8 @@
package org.chromium.latency.walt;
+import static org.chromium.latency.walt.Utils.getBooleanPreference;
+
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
@@ -30,18 +32,6 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.StrictMode;
-import android.preference.PreferenceManager;
-import android.support.annotation.NonNull;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.content.Loader;
-import android.support.v4.content.LocalBroadcastManager;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -49,7 +39,18 @@ import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
-import org.chromium.latency.walt.programmer.Programmer;
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.loader.content.Loader;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+import androidx.preference.PreferenceManager;
import java.io.File;
import java.io.FileOutputStream;
@@ -59,7 +60,7 @@ import java.io.StringWriter;
import java.util.Date;
import java.util.Locale;
-import static org.chromium.latency.walt.Utils.getBooleanPreference;
+import org.chromium.latency.walt.programmer.Programmer;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "WALT";
@@ -218,7 +219,7 @@ public class MainActivity extends AppCompatActivity {
broadcastManager = LocalBroadcastManager.getInstance(this);
// Add basic version and device info to the log
- logger.log(String.format("WALT v%s (versionCode=%d)",
+ logger.log(String.format(Locale.US, "WALT v%s (versionCode=%d)",
BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE));
logger.log("WALT protocol version " + WaltDevice.PROTOCOL_VERSION);
logger.log("DEVICE INFO:");
@@ -325,6 +326,11 @@ public class MainActivity extends AppCompatActivity {
switchScreen(newFragment, "Drag Latency");
}
+ public void onClickAccelerometer(View view) {
+ AccelerometerFragment newFragment = new AccelerometerFragment();
+ switchScreen(newFragment, "Accelerometer Latency");
+ }
+
public void onClickOpenLog(View view) {
LogFragment logFragment = new LogFragment();
// menu.findItem(R.id.action_help).setVisible(false);
@@ -349,13 +355,8 @@ public class MainActivity extends AppCompatActivity {
}
public void onClickPing(View view) {
- long t1 = waltDevice.clock.micros();
try {
- waltDevice.command(WaltDevice.CMD_PING);
- long dt = waltDevice.clock.micros() - t1;
- logger.log(String.format(Locale.US,
- "Ping reply in %.1fms", dt / 1000.
- ));
+ waltDevice.ping();
} catch (IOException e) {
logger.log("Error sending ping: " + e.getMessage());
}
@@ -487,7 +488,7 @@ public class MainActivity extends AppCompatActivity {
// A reasonable world readable location,on many phones it's /storage/emulated/Documents
// TODO: make this location configurable?
- File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
+ File path = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
File file = null;
FileOutputStream outStream = null;
@@ -511,7 +512,7 @@ public class MainActivity extends AppCompatActivity {
}
public void clearLogFile() {
- File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
+ File path = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
try {
File file = new File(path, LOG_FILENAME);
file.delete();
@@ -541,7 +542,8 @@ public class MainActivity extends AppCompatActivity {
}
private static boolean startsWithHttp(String url) {
- return url.toLowerCase().startsWith("http://") || url.toLowerCase().startsWith("https://");
+ return url.toLowerCase(Locale.getDefault()).startsWith("http://") ||
+ url.toLowerCase(Locale.getDefault()).startsWith("https://");
}
private void showUploadLogDialog() {
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/MidiFragment.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/MidiFragment.java
index c6f1118..8d3fe6a 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/MidiFragment.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/MidiFragment.java
@@ -20,13 +20,14 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import androidx.fragment.app.Fragment;
+
import java.util.Locale;
public class MidiFragment extends Fragment
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/NumberPickerPreference.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/NumberPickerPreference.java
index 9d71d42..cf4ef55 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/NumberPickerPreference.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/NumberPickerPreference.java
@@ -19,13 +19,15 @@ package org.chromium.latency.walt;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v7.preference.DialogPreference;
-import android.support.v7.preference.PreferenceDialogFragmentCompat;
import android.util.AttributeSet;
import android.view.View;
+import androidx.annotation.NonNull;
+import androidx.preference.DialogPreference;
+import androidx.preference.PreferenceDialogFragmentCompat;
+
public class NumberPickerPreference extends DialogPreference {
+ private boolean isInitSet = false;
private int currentValue;
private int maxValue;
private int minValue;
@@ -62,9 +64,13 @@ public class NumberPickerPreference extends DialogPreference {
}
public void setValue(int value) {
- currentValue = value;
- persistInt(currentValue);
- setSummary(String.format(defaultSummary, getValue()));
+ boolean changed = (currentValue != value);
+ if (changed || !isInitSet) {
+ isInitSet = true;
+ currentValue = value;
+ persistInt(currentValue);
+ setSummary(String.format(defaultSummary, getValue()));
+ }
}
@Override
@@ -73,8 +79,8 @@ public class NumberPickerPreference extends DialogPreference {
}
@Override
- protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
- setValue(restorePersistedValue ? getPersistedInt(currentValue) : (Integer) defaultValue);
+ protected void onSetInitialValue(Object defaultValue) {
+ setValue((Integer) defaultValue);
}
public static class NumberPickerPreferenceDialogFragmentCompat
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/ScreenResponseFragment.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/ScreenResponseFragment.java
index 629ed7d..d1ebfac 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/ScreenResponseFragment.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/ScreenResponseFragment.java
@@ -16,16 +16,15 @@
package org.chromium.latency.walt;
+import static org.chromium.latency.walt.Utils.getBooleanPreference;
+import static org.chromium.latency.walt.Utils.getIntPreference;
+
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
-import android.support.v4.app.Fragment;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.view.Choreographer;
import android.view.LayoutInflater;
@@ -36,6 +35,11 @@ import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
+
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.data.Entry;
@@ -47,9 +51,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
-import static org.chromium.latency.walt.Utils.getBooleanPreference;
-import static org.chromium.latency.walt.Utils.getIntPreference;
-
/**
* Measurement of screen response time when switching between black and white.
*/
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/SettingsFragment.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/SettingsFragment.java
index 4f74fc4..ace30cc 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/SettingsFragment.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/SettingsFragment.java
@@ -18,19 +18,21 @@ package org.chromium.latency.walt;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v4.content.ContextCompat;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceFragmentCompat;
-import android.support.v7.preference.PreferenceScreen;
-import android.support.v7.widget.Toolbar;
import android.view.View;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.Toolbar;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.PreferenceScreen;
-public class SettingsFragment extends PreferenceFragmentCompat implements PreferenceFragmentCompat.OnPreferenceStartScreenCallback {
+
+public class SettingsFragment extends PreferenceFragmentCompat implements
+ PreferenceFragmentCompat.OnPreferenceStartScreenCallback {
private Toolbar toolbar;
@@ -70,8 +72,8 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Prefer
DialogFragment fragment = NumberPickerPreference.
NumberPickerPreferenceDialogFragmentCompat.newInstance(preference.getKey());
fragment.setTargetFragment(this, 0);
- fragment.show(getFragmentManager(),
- "android.support.v7.preference.PreferenceFragment.DIALOG");
+ fragment.show(getParentFragmentManager(),
+ "androidx.preference.PreferenceFragment.DIALOG");
} else {
super.onDisplayPreferenceDialog(preference);
}
@@ -90,7 +92,8 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Prefer
args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, preferenceScreen.getKey());
fragment.setArguments(args);
- FragmentTransaction ft = preferenceFragmentCompat.getFragmentManager().beginTransaction();
+ FragmentTransaction ft = preferenceFragmentCompat.
+ getParentFragmentManager().beginTransaction();
ft.add(R.id.fragment_container, fragment, preferenceScreen.getKey());
ft.addToBackStack(preferenceScreen.getTitle().toString());
ft.commit();
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/SimpleLogger.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/SimpleLogger.java
index 6059e0f..9244377 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/SimpleLogger.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/SimpleLogger.java
@@ -20,7 +20,9 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.support.v4.content.LocalBroadcastManager;
+
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+
import android.util.Log;
/**
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/TapLatencyFragment.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/TapLatencyFragment.java
index e26a328..ca0e80b 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/TapLatencyFragment.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/TapLatencyFragment.java
@@ -16,11 +16,11 @@
package org.chromium.latency.walt;
+import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -29,6 +29,8 @@ import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
+import androidx.fragment.app.Fragment;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.Locale;
@@ -71,6 +73,7 @@ public class TapLatencyFragment extends Fragment
}
};
+ @SuppressLint("ClickableViewAccessibility")
private View.OnTouchListener touchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
@@ -212,6 +215,7 @@ public class TapLatencyFragment extends Fragment
moveCountsView.setText(String.format(Locale.US, "⇄ %d", moveCount));
}
+ @SuppressLint("ClickableViewAccessibility")
void restartMeasurement() {
logger.log("\n## Restarting tap latency measurement. Re-sync clocks ...");
try {
@@ -241,6 +245,7 @@ public class TapLatencyFragment extends Fragment
tapCatcherView.setOnTouchListener(touchListener);
}
+ @SuppressLint("ClickableViewAccessibility")
void finishAndShowStats() {
tapCatcherView.setOnTouchListener(null);
waltDevice.checkDrift();
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/TraceLogger.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/TraceLogger.java
index 6fdb8d9..964e9c6 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/TraceLogger.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/TraceLogger.java
@@ -25,6 +25,7 @@ import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.DecimalFormat;
import java.util.ArrayList;
+import java.util.Locale;
/**
* Used to log events for Android systrace
@@ -58,12 +59,13 @@ class TraceLogger {
StringBuilder sb = new StringBuilder();
int pid = android.os.Process.myPid();
for (TraceEvent e : traceEvents) {
- sb.append(String.format(
- "WALTThread-1234 (%d) [000] ...1 %s: tracing_mark_write: B|%d|%s|description=%s|WALT\n",
- pid, df.format(e.startTimeMicros / 1e6), pid, e.title, e.description));
- sb.append(String.format(
- "WALTThread-1234 (%d) [000] ...1 %s: tracing_mark_write: E|%d|%s||WALT\n",
- pid, df.format(e.finishTimeMicros / 1e6), pid, e.title));
+ sb.append(String.format(Locale.US,
+ "WALTThread-1234 (%d) [000] ...1 %s: tracing_mark_write: "
+ + "B|%d|%s|description=%s|WALT\n",
+ pid, df.format(e.startTimeMicros / 1e6), pid, e.title, e.description));
+ sb.append(String.format(Locale.US,
+ "WALTThread-1234 (%d) [000] ...1 %s: tracing_mark_write: E|%d|%s||WALT\n",
+ pid, df.format(e.finishTimeMicros / 1e6), pid, e.title));
}
return sb.toString();
}
@@ -85,7 +87,7 @@ class TraceLogger {
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file, true));
writer.write(getLogText());
writer.close();
- logger.log(String.format("TraceLogger wrote %d events to %s",
+ logger.log(String.format(Locale.US, "TraceLogger wrote %d events to %s",
traceEvents.size(), file.getAbsolutePath()));
} catch (IOException e) {
logger.log("ERROR: IOException writing to trace.txt");
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/UsMotionEvent.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/UsMotionEvent.java
index e961949..f68e461 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/UsMotionEvent.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/UsMotionEvent.java
@@ -20,6 +20,7 @@ import android.util.Log;
import android.view.MotionEvent;
import java.lang.reflect.Method;
+import java.util.Locale;
/**
* A convenient representation of MotionEvent events
@@ -71,13 +72,13 @@ public class UsMotionEvent {
public String toString() {
- return String.format("%d %f %f",
+ return String.format(Locale.US, "%d %f %f",
kernelTime, x, y);
}
public String toStringLong() {
- return String.format("Event: t=%d x=%.1f y=%.1f slot=%d num=%d %s",
+ return String.format(Locale.US, "Event: t=%d x=%.1f y=%.1f slot=%d num=%d %s",
kernelTime, x, y, slot, num, actionToString(action));
}
@@ -119,7 +120,7 @@ public class UsMotionEvent {
private long getEventTimeMicro(MotionEvent event) {
long t_nanos = -1;
try {
- Class cls = Class.forName("android.view.MotionEvent");
+ Class<?> cls = Class.forName("android.view.MotionEvent");
Method myTimeGetter = cls.getMethod("getEventTimeNano");
t_nanos = (long) myTimeGetter.invoke(event);
} catch (Exception e) {
@@ -132,7 +133,7 @@ public class UsMotionEvent {
private long getHistoricalEventTimeMicro(MotionEvent event, int pos) {
long t_nanos = -1;
try {
- Class cls = Class.forName("android.view.MotionEvent");
+ Class<?> cls = Class.forName("android.view.MotionEvent");
Method myTimeGetter = cls.getMethod("getHistoricalEventTimeNano", new Class[] {int.class});
t_nanos = (long) myTimeGetter.invoke(event, new Object[]{pos});
} catch (Exception e) {
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/Utils.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/Utils.java
index 19c7488..46796e2 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/Utils.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/Utils.java
@@ -18,11 +18,15 @@ package org.chromium.latency.walt;
import android.content.Context;
import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-import android.support.annotation.StringRes;
+
+import androidx.preference.PreferenceManager;
+import androidx.annotation.StringRes;
+
+import com.github.mikephil.charting.data.Entry;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
/**
* Kitchen sink for small utility functions
@@ -120,6 +124,11 @@ public class Utils {
return sb.toString();
}
+ public static int argmax(double[] a) {
+ int imax = 0;
+ for (int i=1; i<a.length; i++) if (a[i] > a[imax]) imax = i;
+ return imax;
+ }
public static int argmin(double[] a) {
int imin = 0;
@@ -177,6 +186,30 @@ public class Utils {
return preferences.getString(context.getString(keyId), defaultValue);
}
+ static float min(List<Entry> entries) {
+ float min = Float.MAX_VALUE;
+ for (Entry e : entries) {
+ min = Math.min(min, e.getY());
+ }
+ return min;
+ }
+
+ static float max(List<Entry> entries) {
+ float max = Float.MIN_VALUE;
+ for (Entry e : entries) {
+ max = Math.max(max, e.getY());
+ }
+ return max;
+ }
+
+ static float mean(List<Entry> entries) {
+ float mean = 0;
+ for (Entry e : entries) {
+ mean += e.getY()/entries.size();
+ }
+ return mean;
+ }
+
public enum ListenerState {
RUNNING,
STARTING,
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/WaltDevice.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/WaltDevice.java
index 8ec2cb4..631afb8 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/WaltDevice.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/WaltDevice.java
@@ -23,6 +23,7 @@ import android.os.Handler;
import android.util.Log;
import java.io.IOException;
+import java.util.Locale;
/**
* A singleton used as an interface for the physical WALT device.
@@ -31,7 +32,7 @@ public class WaltDevice implements WaltConnection.ConnectionStateListener {
private static final int DEFAULT_DRIFT_LIMIT_US = 1500;
private static final String TAG = "WaltDevice";
- public static final String PROTOCOL_VERSION = "5";
+ public static final String PROTOCOL_VERSION = "6";
// Teensy side commands. Each command is a single char
// Based on #defines section in walt.ino
@@ -56,6 +57,7 @@ public class WaltDevice implements WaltConnection.ConnectionStateListener {
static final char CMD_BEEP_STOP = 'S'; // Stop generating tone
static final char CMD_MIDI = 'M'; // Start listening for a MIDI message
static final char CMD_NOTE = 'N'; // Generate a MIDI NoteOn message
+ static final char CMD_ACCELEROMETER = 'O'; // Generate a MIDI NoteOn message
private static final int BYTE_BUFFER_SIZE = 1024 * 4;
private byte[] buffer = new byte[BYTE_BUFFER_SIZE];
@@ -221,6 +223,19 @@ public class WaltDevice implements WaltConnection.ConnectionStateListener {
}
}
+ public void ping() throws IOException {
+ if (!isConnected() || clock == null) {
+ throw new IOException("Not connected to WALT");
+ }
+
+ long t1 = clock.micros();
+ command(CMD_PING);
+ long dt = clock.micros() - t1;
+ logger.log(String.format(Locale.US,
+ "Ping reply in %.1fms", dt / 1000.
+ ));
+ }
+
public void syncClock() throws IOException {
clock = connection.syncClock();
}
@@ -247,7 +262,7 @@ public class WaltDevice implements WaltConnection.ConnectionStateListener {
return;
}
int drift = Math.abs(clock.getMeanLag());
- String msg = String.format("Remote clock delayed between %d and %d us",
+ String msg = String.format(Locale.US, "Remote clock delayed between %d and %d us",
clock.minLag, clock.maxLag);
// TODO: Convert the limit to user editable preference
if (drift > DEFAULT_DRIFT_LIMIT_US) {
diff --git a/android/WALT/app/src/main/java/org/chromium/latency/walt/programmer/FirmwareImage.java b/android/WALT/app/src/main/java/org/chromium/latency/walt/programmer/FirmwareImage.java
index d2feb01..0f8b1ef 100644
--- a/android/WALT/app/src/main/java/org/chromium/latency/walt/programmer/FirmwareImage.java
+++ b/android/WALT/app/src/main/java/org/chromium/latency/walt/programmer/FirmwareImage.java
@@ -24,6 +24,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.util.Arrays;
+import java.util.Locale;
class FirmwareImage {
private static final String TAG = "FirmwareImage";
@@ -89,7 +90,8 @@ class FirmwareImage {
return;
}
default: {
- throw new ParseException(String.format("Unknown code '%x'", code), cur);
+ throw new ParseException(String.format(
+ Locale.US, "Unknown code '%x'", code), cur);
}
}
}
@@ -119,8 +121,8 @@ class FirmwareImage {
dest[addr + i] = parseByte(line, pos + i * 2);
mask[addr + i] = true;
} catch (ArrayIndexOutOfBoundsException e) {
- throw new ParseException(String.format("Address '%x' out of range", addr + i),
- pos + i * 2);
+ throw new ParseException(String.format(Locale.US,
+ "Address '%x' out of range", addr + i), pos + i * 2);
}
}
}