Indicate sensor discontinuity via SensorEvent

Use a bool in SensorEvent rather than a new method in
SensorEventCallback to indicate discontinuities.

Fixes: 217364461
Test: additional CTS test cases pending
CTS-Coverage-Bug: 214618172
Change-Id: I144487d36b2d00d57265c9e3e9f542c7136a33f5
diff --git a/core/api/current.txt b/core/api/current.txt
index 4d1e280..422fdd0 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -16988,6 +16988,7 @@
 
   public class SensorEvent {
     field public int accuracy;
+    field public boolean firstEventAfterDiscontinuity;
     field public android.hardware.Sensor sensor;
     field public long timestamp;
     field public final float[] values;
@@ -16999,7 +17000,6 @@
     method public void onFlushCompleted(android.hardware.Sensor);
     method public void onSensorAdditionalInfo(android.hardware.SensorAdditionalInfo);
     method public void onSensorChanged(android.hardware.SensorEvent);
-    method public void onSensorDiscontinuity(@NonNull android.hardware.Sensor);
   }
 
   public interface SensorEventListener {
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index f68fb9d..6113932 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -17,6 +17,7 @@
 package android.hardware;
 
 import android.annotation.NonNull;
+import android.annotation.SuppressLint;
 import android.compat.annotation.UnsupportedAppUsage;
 
 /**
@@ -824,6 +825,21 @@
      */
     public long timestamp;
 
+    /**
+     * Set to true when this is the first sensor event after a discontinuity.
+     *
+     * The exact meaning of discontinuity depends on the sensor type. For
+     * {@link android.hardware.Sensor#TYPE_HEAD_TRACKER Sensor.TYPE_HEAD_TRACKER}, this means that
+     * the reference frame has suddenly and significantly changed, for example if the head tracking
+     * device was removed then put back.
+     *
+     * Note that this concept is either not relevant to or not supported by most sensor types,
+     * {@link android.hardware.Sensor#TYPE_HEAD_TRACKER Sensor.TYPE_HEAD_TRACKER} being the notable
+     * exception.
+     */
+    @SuppressLint("MutableBareField")
+    public boolean firstEventAfterDiscontinuity;
+
     @UnsupportedAppUsage
     SensorEvent(int valueSize) {
         values = new float[valueSize];
diff --git a/core/java/android/hardware/SensorEventCallback.java b/core/java/android/hardware/SensorEventCallback.java
index 7b0092d..bac212a 100644
--- a/core/java/android/hardware/SensorEventCallback.java
+++ b/core/java/android/hardware/SensorEventCallback.java
@@ -16,8 +16,6 @@
 
 package android.hardware;
 
-import android.annotation.NonNull;
-
 /**
  * Used for receiving sensor additional information frames.
  */
@@ -54,21 +52,4 @@
      * reported from sensor hardware.
      */
     public void onSensorAdditionalInfo(SensorAdditionalInfo info) {}
-
-    /**
-     * Called when the next {@link android.hardware.SensorEvent SensorEvent} to be delivered via the
-     * {@link #onSensorChanged(SensorEvent) onSensorChanged} method represents the first event after
-     * a discontinuity.
-     *
-     * The exact meaning of discontinuity depends on the sensor type. For {@link
-     * android.hardware.Sensor#TYPE_HEAD_TRACKER Sensor.TYPE_HEAD_TRACKER}, this means that the
-     * reference frame has suddenly and significantly changed.
-     *
-     * Note that this concept is either not relevant to or not supported by most sensor types,
-     * {@link android.hardware.Sensor#TYPE_HEAD_TRACKER Sensor.TYPE_HEAD_TRACKER} being the notable
-     * exception.
-     *
-     * @param sensor The {@link android.hardware.Sensor Sensor} which experienced the discontinuity.
-     */
-    public void onSensorDiscontinuity(@NonNull Sensor sensor) {}
 }
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 32a5ee7..18d86d6 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -881,13 +881,13 @@
                 mListener.onAccuracyChanged(t.sensor, t.accuracy);
             }
 
-            // call onSensorDiscontinuity() if the discontinuity counter changed
-            if (t.sensor.getType() == Sensor.TYPE_HEAD_TRACKER
-                    && mListener instanceof SensorEventCallback) {
+            // Indicate if the discontinuity count changed
+            if (t.sensor.getType() == Sensor.TYPE_HEAD_TRACKER) {
                 final int lastCount = mSensorDiscontinuityCounts.get(handle);
                 final int curCount = Float.floatToIntBits(values[6]);
                 if (lastCount >= 0 && lastCount != curCount) {
-                    ((SensorEventCallback) mListener).onSensorDiscontinuity(t.sensor);
+                    mSensorDiscontinuityCounts.put(handle, curCount);
+                    t.firstEventAfterDiscontinuity = true;
                 }
             }