Fix janky scrolling for Gestures Settings.

1. Move the media player initialization/cleanup to construstor and
onDetach() of GesturePreference correspondingly, so that it's only
done once instead of every time when a new texture surface is available.
2. Pause the animation video when user scrolls.

Bug: 29790087
Change-Id: I51e6a787f9f2964b6bfc5288f7f5af801ccecc31
diff --git a/src/com/android/settings/gestures/GesturePreference.java b/src/com/android/settings/gestures/GesturePreference.java
index cad7297..c6ee0a7 100644
--- a/src/com/android/settings/gestures/GesturePreference.java
+++ b/src/com/android/settings/gestures/GesturePreference.java
@@ -17,22 +17,16 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.PorterDuff;
 import android.graphics.SurfaceTexture;
 import android.media.MediaMetadataRetriever;
 import android.media.MediaPlayer;
 import android.net.Uri;
 import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.PreferenceViewHolder;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.Surface;
 import android.view.TextureView;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
 import android.util.AttributeSet;
 import android.util.Log;
 
@@ -52,6 +46,7 @@
     private MediaMetadataRetriever mMediaMetadata;
     private boolean mAnimationAvailable;
     private boolean mPreviewReady;
+    private boolean mScrolling;
 
     public GesturePreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -69,6 +64,23 @@
                     .build();
             mMediaMetadata = new MediaMetadataRetriever();
             mMediaMetadata.setDataSource(mContext, mVideoPath);
+            mMediaPlayer = MediaPlayer.create(mContext, mVideoPath);
+            if (mMediaPlayer != null) {
+                mMediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
+                    @Override
+                    public void onSeekComplete(MediaPlayer mp) {
+                        mPreviewReady = true;
+                        mMediaPlayer.setOnSeekCompleteListener(null);
+                    }
+                });
+
+                mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
+                    @Override
+                    public void onPrepared(MediaPlayer mediaPlayer) {
+                        mediaPlayer.setLooping(true);
+                    }
+                });
+            }
             mAnimationAvailable = true;
         } catch (Exception e) {
             Log.w(TAG, "Animation resource not found. Will not show animation.");
@@ -111,25 +123,9 @@
             @Override
             public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width,
                     int height) {
-                mMediaPlayer = MediaPlayer.create(mContext, mVideoPath);
                 if (mMediaPlayer != null) {
                     mMediaPlayer.setSurface(new Surface(surfaceTexture));
-                    mMediaPlayer.setOnSeekCompleteListener(
-                            new MediaPlayer.OnSeekCompleteListener() {
-                                @Override
-                                public void onSeekComplete(MediaPlayer mp) {
-                                    mPreviewReady = true;
-                                    mMediaPlayer.setOnSeekCompleteListener(null);
-                                }
-                            });
-
-                    mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
-                        @Override
-                        public void onPrepared(MediaPlayer mediaPlayer) {
-                            mediaPlayer.seekTo(0);
-                            mediaPlayer.setLooping(true);
-                        }
-                    });
+                    mMediaPlayer.seekTo(0);
                 }
             }
 
@@ -140,12 +136,6 @@
 
             @Override
             public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
-                imageView.setVisibility(View.VISIBLE);
-                if (mMediaPlayer != null) {
-                    mMediaPlayer.stop();
-                    mMediaPlayer.reset();
-                    mMediaPlayer.release();
-                }
                 return false;
             }
 
@@ -153,6 +143,12 @@
             public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
                 if (mPreviewReady && imageView.getVisibility() == View.VISIBLE) {
                     imageView.setVisibility(View.GONE);
+                } else if (mScrolling) {
+                    mScrolling = false;
+                    if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
+                        mMediaPlayer.pause();
+                        playButton.setVisibility(View.VISIBLE);
+                    }
                 }
             }
         });
@@ -161,8 +157,19 @@
 
     @Override
     public void onDetached() {
-        mMediaMetadata.release();
+        if (mMediaMetadata != null) {
+            mMediaMetadata.release();
+        }
+        if (mMediaPlayer != null) {
+            mMediaPlayer.stop();
+            mMediaPlayer.reset();
+            mMediaPlayer.release();
+        }
         super.onDetached();
     }
 
+    void setScrolling(boolean scrolling) {
+        mScrolling = scrolling;
+    }
+
 }
diff --git a/src/com/android/settings/gestures/GestureSettings.java b/src/com/android/settings/gestures/GestureSettings.java
index 2c065ac..3171a9f 100644
--- a/src/com/android/settings/gestures/GestureSettings.java
+++ b/src/com/android/settings/gestures/GestureSettings.java
@@ -28,7 +28,6 @@
 import android.support.v7.preference.Preference;
 import android.support.v7.widget.RecyclerView;
 import android.text.TextUtils;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -59,42 +58,35 @@
     private static final String ARG_SCROLL_TO_PREFERENCE = "gesture_scroll_to_preference";
 
     private int mScrollPosition = -1;
+    private List<GesturePreference> mPreferences;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         addPreferencesFromResource(R.xml.gesture_settings);
         Context context = getActivity();
+        mPreferences = new ArrayList();
 
          // Double tap power for camera
         if (isCameraDoubleTapPowerGestureAvailable(getResources())) {
             int cameraDisabled = Secure.getInt(
                     getContentResolver(), Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0);
-            GesturePreference preference =
-                    (GesturePreference) findPreference(PREF_KEY_DOUBLE_TAP_POWER);
-            preference.setChecked(cameraDisabled == 0);
-            preference.setOnPreferenceChangeListener(this);
+            addPreference(PREF_KEY_DOUBLE_TAP_POWER, cameraDisabled == 0);
         } else {
             removePreference(PREF_KEY_DOUBLE_TAP_POWER);
         }
 
         // Ambient Display
         if (isDozeAvailable(context)) {
-            GesturePreference preference =
-                    (GesturePreference) findPreference(PREF_KEY_PICK_UP_AND_NUDGE);
             int dozeEnabled = Secure.getInt(getContentResolver(), Secure.DOZE_ENABLED, 1);
-            preference.setChecked(dozeEnabled != 0);
-            preference.setOnPreferenceChangeListener(this);
+            addPreference(PREF_KEY_PICK_UP_AND_NUDGE, dozeEnabled != 0);
         } else {
             removePreference(PREF_KEY_PICK_UP_AND_NUDGE);
         }
 
         // Fingerprint slide for notifications
         if (isSystemUINavigationAvailable(context)) {
-            GesturePreference preference =
-                    (GesturePreference) findPreference(PREF_KEY_SWIPE_DOWN_FINGERPRINT);
-            preference.setChecked(isSystemUINavigationEnabled(context));
-            preference.setOnPreferenceChangeListener(this);
+            addPreference(PREF_KEY_SWIPE_DOWN_FINGERPRINT, isSystemUINavigationEnabled(context));
         } else {
             removePreference(PREF_KEY_SWIPE_DOWN_FINGERPRINT);
         }
@@ -103,10 +95,7 @@
         if (isDoubleTwistAvailable(context)) {
             int doubleTwistEnabled = Secure.getInt(
                     getContentResolver(), Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, 1);
-            GesturePreference preference =
-                    (GesturePreference) findPreference(PREF_KEY_DOUBLE_TWIST);
-            preference.setChecked(doubleTwistEnabled != 0);
-            preference.setOnPreferenceChangeListener(this);
+            addPreference(PREF_KEY_DOUBLE_TWIST, doubleTwistEnabled != 0);
         } else {
             removePreference(PREF_KEY_DOUBLE_TWIST);
         }
@@ -128,9 +117,28 @@
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                              Bundle savedInstanceState) {
         View view = super.onCreateView(inflater, container, savedInstanceState);
+        RecyclerView listview = getListView();
         if (mScrollPosition >= 0) {
-            getListView().scrollToPosition(mScrollPosition);
+            listview.scrollToPosition(mScrollPosition);
         }
+        listview.addOnScrollListener(new RecyclerView.OnScrollListener() {
+            @Override
+            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+                if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
+                    for (GesturePreference pref : mPreferences) {
+                        pref.setScrolling(true);
+                    }
+                } else if (newState == RecyclerView.SCROLL_STATE_IDLE) {
+                    for (GesturePreference pref : mPreferences) {
+                        pref.setScrolling(false);
+                    }
+                }
+            }
+
+            @Override
+            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+            }
+        });
         return view;
     }
 
@@ -203,6 +211,13 @@
         return false;
     }
 
+    private void addPreference(String key, boolean enabled) {
+        GesturePreference preference = (GesturePreference) findPreference(key);
+        preference.setChecked(enabled);
+        preference.setOnPreferenceChangeListener(this);
+        mPreferences.add(preference);
+    }
+
     public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
         new BaseSearchIndexProvider() {
             @Override