Fix layout transition from Display->Ambient Display to Gestures

1. Add handling in Gestures settings to scroll to the corresponding
preference when launching from Display->Ambient Display
2. Remove the bitmap creation for the video preview image
3. Use a custom aspect ration framee layout to hold the animation
instead to avoid resizing of the animation view.

Bug: 29795707
Change-Id: I67209ba2508a93da4fc46ff20986309dbe5a83d5
diff --git a/res/layout/gesture_preference.xml b/res/layout/gesture_preference.xml
index 71fe86f..ebb43a4 100644
--- a/res/layout/gesture_preference.xml
+++ b/res/layout/gesture_preference.xml
@@ -57,7 +57,7 @@
         android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
         android:orientation="horizontal">
 
-        <FrameLayout
+        <com.android.settings.widget.AspectRatioFrameLayout
             android:id="@+id/gesture_animation_frame"
             android:layout_width="0dp"
             android:layout_height="match_parent"
@@ -73,7 +73,7 @@
                 android:id="@+id/gesture_image"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                android:visibility="gone"/>
+                android:background="@color/gestures_setting_background_color"/>
 
             <ImageView
                 android:id="@+id/gesture_play_button"
@@ -81,10 +81,9 @@
                 android:layout_height="@dimen/gestures_play_button_size"
                 android:src="@drawable/ic_gesture_play_button"
                 android:gravity="center"
-                android:layout_gravity="center"
-                android:visibility="gone"/>
+                android:layout_gravity="center"/>
 
-        </FrameLayout>
+        </com.android.settings.widget.AspectRatioFrameLayout>
 
         <TextView
             android:id="@android:id/summary"
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 8fb61dd..218d7f2 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -141,4 +141,9 @@
         <attr name="animation" format="reference" />
     </declare-styleable>
 
+    <!-- For AspectRatioFrameLayout -->
+    <declare-styleable name="AspectRatioFrameLayout">
+        <attr name="aspectRatio" format="float" />
+    </declare-styleable>
+
 </resources>
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index cb1fac5..b540c8f 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -77,7 +77,7 @@
                 android:title="@string/doze_title"
                 android:summary="@string/doze_summary"
                 android:fragment="com.android.settings.gestures.GestureSettings" >
-                <extra android:name=":settings:fragment_args_key"
+                <extra android:name="gesture_scroll_to_preference"
                        android:value="gesture_pick_up_and_nudge" />
         </PreferenceScreen>
 
diff --git a/src/com/android/settings/gestures/GesturePreference.java b/src/com/android/settings/gestures/GesturePreference.java
index 76ceba4..cad7297 100644
--- a/src/com/android/settings/gestures/GesturePreference.java
+++ b/src/com/android/settings/gestures/GesturePreference.java
@@ -50,7 +50,8 @@
     private Uri mVideoPath;
     private MediaPlayer mMediaPlayer;
     private MediaMetadataRetriever mMediaMetadata;
-    private boolean animationAvailable;
+    private boolean mAnimationAvailable;
+    private boolean mPreviewReady;
 
     public GesturePreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -68,7 +69,7 @@
                     .build();
             mMediaMetadata = new MediaMetadataRetriever();
             mMediaMetadata.setDataSource(mContext, mVideoPath);
-            animationAvailable = true;
+            mAnimationAvailable = true;
         } catch (Exception e) {
             Log.w(TAG, "Animation resource not found. Will not show animation.");
         } finally {
@@ -86,20 +87,11 @@
         final ImageView playButton = (ImageView) holder.findViewById(R.id.gesture_play_button);
         final View animationFrame = holder.findViewById(R.id.gesture_animation_frame);
 
-        if (!animationAvailable) {
+        if (!mAnimationAvailable) {
             animationFrame.setVisibility(View.GONE);
             return;
         }
 
-        Bitmap bitmap = mMediaMetadata.getFrameAtTime(0);
-        if (bitmap != null) {
-            imageView.setImageDrawable(new BitmapDrawable(bitmap));
-            imageView.setColorFilter(mContext.getResources().getColor(
-                    R.color.gestures_setting_background_color), PorterDuff.Mode.DARKEN);
-        }
-        imageView.setVisibility(View.VISIBLE);
-        playButton.setVisibility(View.VISIBLE);
-
         video.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -119,13 +111,22 @@
             @Override
             public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width,
                     int height) {
-                animationFrame.setLayoutParams(new LinearLayout.LayoutParams(width, width));
                 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);
                         }
                     });
@@ -150,7 +151,7 @@
 
             @Override
             public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
-                if (mMediaPlayer.isPlaying() && imageView.getVisibility() == View.VISIBLE) {
+                if (mPreviewReady && imageView.getVisibility() == View.VISIBLE) {
                     imageView.setVisibility(View.GONE);
                 }
             }
diff --git a/src/com/android/settings/gestures/GestureSettings.java b/src/com/android/settings/gestures/GestureSettings.java
index cafba68..a24d810 100644
--- a/src/com/android/settings/gestures/GestureSettings.java
+++ b/src/com/android/settings/gestures/GestureSettings.java
@@ -25,8 +25,12 @@
 import android.provider.Settings.Global;
 import android.provider.Settings.Secure;
 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;
 
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settings.R;
@@ -51,6 +55,9 @@
     private static final String PREF_KEY_PICK_UP_AND_NUDGE = "gesture_pick_up_and_nudge";
     private static final String PREF_KEY_SWIPE_DOWN_FINGERPRINT = "gesture_swipe_down_fingerprint";
     private static final String DEBUG_DOZE_COMPONENT = "debug.doze.component";
+    private static final String ARG_SCROLL_TO_PREFERENCE = "gesture_scroll_to_preference";
+
+    private int mScrollPosition = -1;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -91,6 +98,27 @@
             removePreference(PREF_KEY_SWIPE_DOWN_FINGERPRINT);
         }
 
+        if (savedInstanceState == null) {
+            final Bundle args = getArguments();
+            if (args != null && args.containsKey(ARG_SCROLL_TO_PREFERENCE)) {
+                String prefKey = args.getString(ARG_SCROLL_TO_PREFERENCE);
+                GesturePreference pref = (GesturePreference) findPreference(prefKey);
+                if (pref != null) {
+                    mScrollPosition = pref.getOrder();
+                }
+            }
+        }
+
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        View view = super.onCreateView(inflater, container, savedInstanceState);
+        if (mScrollPosition >= 0) {
+            getListView().scrollToPosition(mScrollPosition);
+        }
+        return view;
     }
 
     @Override
diff --git a/src/com/android/settings/widget/AspectRatioFrameLayout.java b/src/com/android/settings/widget/AspectRatioFrameLayout.java
new file mode 100644
index 0000000..14d7921
--- /dev/null
+++ b/src/com/android/settings/widget/AspectRatioFrameLayout.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 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 com.android.settings.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+import com.android.settings.R;
+
+/**
+ * A {@link FrameLayout} with customizable aspect ration.
+ * This is used to avoid dynamically calculating the height for the frame. Default aspect
+ * ratio will be 1 if none is set in layout attribute.
+ */
+public final class AspectRatioFrameLayout extends FrameLayout {
+
+    private float mAspectRatio = 1.0f;
+
+    public AspectRatioFrameLayout(Context context) {
+        this(context, null);
+    }
+
+    public AspectRatioFrameLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public AspectRatioFrameLayout(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        if (attrs != null) {
+            TypedArray array =
+                    context.obtainStyledAttributes(attrs, R.styleable.AspectRatioFrameLayout);
+            mAspectRatio = array.getFloat(
+                    R.styleable.AspectRatioFrameLayout_aspectRatio, 1.0f);
+            array.recycle();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, (int) (widthMeasureSpec / mAspectRatio));
+    }
+
+}