1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.input.motionprediction; 18 19 import android.content.Context; 20 import android.os.Build; 21 import android.view.MotionEvent; 22 import android.view.View; 23 24 import androidx.annotation.NonNull; 25 import androidx.annotation.Nullable; 26 import androidx.input.motionprediction.common.Configuration; 27 import androidx.input.motionprediction.kalman.KalmanMotionEventPredictor; 28 import androidx.input.motionprediction.system.SystemMotionEventPredictor; 29 30 /** 31 * There is a gap between the time a user touches the screen and that information is reported to the 32 * app; a motion predictor is a utility that provides predicted {@link android.view.MotionEvent} 33 * based on the previously received ones. Obtain a new predictor instance using 34 * {@link #newInstance(android.view.View)}; put the motion events you receive into it with 35 * {@link #record(android.view.MotionEvent)}, and call {@link #predict()} to retrieve the 36 * predicted {@link android.view.MotionEvent} that would occur at the moment the next frame is 37 * rendered on the display. 38 */ 39 public interface MotionEventPredictor { 40 /** 41 * Record a user's movement to the predictor. You should call this for every 42 * {@link android.view.MotionEvent} that is received by the associated 43 * {@link android.view.View}. 44 * 45 * @param event the {@link android.view.MotionEvent} the associated view received and that 46 * needs to be recorded. 47 * @throws IllegalArgumentException if an inconsistent MotionEvent stream is sent. 48 */ record(@onNull MotionEvent event)49 void record(@NonNull MotionEvent event); 50 51 /** 52 * Compute a prediction 53 * 54 * @return the predicted {@link android.view.MotionEvent}, or null if not possible to make a 55 * prediction. 56 */ 57 @Nullable predict()58 MotionEvent predict(); 59 60 /** 61 * Create a new motion predictor associated to a specific {@link android.view.View}. 62 * 63 * For devices running Android versions before U, the predicions are provided by a library based 64 * on a Kalman filter; from Android U, a system API is available, but predictions may not be 65 * supported for all strokes (for instance, it may be limited to stylus events). In these cases, 66 * the Kalman filter library will be used; to determine if a `MotionEvent` will be handled by 67 * the system prediction, use {@link android.view.MotionPredictor#isPredictionAvailable}. 68 * 69 * @param view the view to associated to this predictor 70 * @return the new predictor instance 71 */ 72 @NonNull newInstance(@onNull View view)73 static MotionEventPredictor newInstance(@NonNull View view) { 74 Context context = view.getContext(); 75 Configuration configuration = Configuration.getInstance(); 76 if (Build.VERSION.SDK_INT >= 34 77 && configuration.preferSystemPrediction()) { 78 return SystemMotionEventPredictor.newInstance( 79 context, 80 configuration.predictionStrategy()); 81 } else { 82 return new KalmanMotionEventPredictor(context, configuration.predictionStrategy()); 83 } 84 } 85 } 86