Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8668aa0a authored by Doris Ling's avatar Doris Ling Committed by android-build-merger
Browse files

Merge \"Get gestures animation preview image in async loader.\" into nyc-mr1-dev

am: fd922cab

Change-Id: I6975f268808cd5f9521cba6922120c667010023d
parents 1da5d326 fd922cab
Loading
Loading
Loading
Loading
+73 −11
Original line number Diff line number Diff line
@@ -14,13 +14,18 @@

package com.android.settings.gestures;

import android.app.LoaderManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Loader;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.SurfaceTexture;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.PreferenceViewHolder;
import android.view.View;
@@ -31,22 +36,24 @@ import android.util.AttributeSet;
import android.util.Log;

import com.android.settings.R;
import com.android.settings.utils.AsyncLoader;

/**
 * Preference item for a gesture with a switch to signify if it should be enabled.
 * This shows the title and description of the gesture along with an animation showing how to do
 * the gesture
 */
public final class GesturePreference extends SwitchPreference {
public final class GesturePreference extends SwitchPreference implements
        LoaderManager.LoaderCallbacks<Bitmap> {
    private static final String TAG = "GesturePreference";
    private final Context mContext;

    private Uri mVideoPath;
    private MediaPlayer mMediaPlayer;
    private MediaMetadataRetriever mMediaMetadata;
    private boolean mAnimationAvailable;
    private boolean mPreviewReady;
    private boolean mVideoReady;
    private boolean mScrolling;
    private BitmapDrawable mPreviewImage;

    public GesturePreference(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -62,15 +69,12 @@ public final class GesturePreference extends SwitchPreference {
                    .authority(context.getPackageName())
                    .appendPath(String.valueOf(animation))
                    .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);
                        mVideoReady = true;
                    }
                });

@@ -82,6 +86,7 @@ public final class GesturePreference extends SwitchPreference {
                });
            }
            mAnimationAvailable = true;

        } catch (Exception e) {
            Log.w(TAG, "Animation resource not found. Will not show animation.");
        } finally {
@@ -125,6 +130,7 @@ public final class GesturePreference extends SwitchPreference {
                    int height) {
                if (mMediaPlayer != null) {
                    mMediaPlayer.setSurface(new Surface(surfaceTexture));
                    mVideoReady = false;
                    mMediaPlayer.seekTo(0);
                }
            }
@@ -136,12 +142,16 @@ public final class GesturePreference extends SwitchPreference {

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
                if (mPreviewImage != null && imageView.getDrawable() == null) {
                    imageView.setImageDrawable(mPreviewImage);
                }
                imageView.setVisibility(View.VISIBLE);
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
                if (mPreviewReady && imageView.getVisibility() == View.VISIBLE) {
                if (mVideoReady && imageView.getVisibility() == View.VISIBLE) {
                    imageView.setVisibility(View.GONE);
                } else if (mScrolling) {
                    mScrolling = false;
@@ -153,13 +163,14 @@ public final class GesturePreference extends SwitchPreference {
            }
        });

        if (mPreviewImage != null) {
            imageView.setImageDrawable(mPreviewImage);
        }

    }

    @Override
    public void onDetached() {
        if (mMediaMetadata != null) {
            mMediaMetadata.release();
        }
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            mMediaPlayer.reset();
@@ -172,4 +183,55 @@ public final class GesturePreference extends SwitchPreference {
        mScrolling = scrolling;
    }

    void loadPreview(LoaderManager manager, int id) {
        Loader<Bitmap> loader = manager.initLoader(id, Bundle.EMPTY, this);
    }

    private static final class PreviewRetriever extends AsyncLoader<Bitmap> {
        private Uri mVideoPath;

        public PreviewRetriever(Context context, Uri videoPath) {
            super(context);
            mVideoPath = videoPath;
        }

        @Override
        public Bitmap loadInBackground() {
            MediaMetadataRetriever mediaMetadata = new MediaMetadataRetriever();
            try {
                mediaMetadata.setDataSource(getContext(), mVideoPath);
                return mediaMetadata.getFrameAtTime(0);
            } catch (Exception e) {
                Log.w(TAG, "Unable to get animation preview.");
            } finally {
                mediaMetadata.release();
            }
            return null;
        }

        @Override
        public void onDiscardResult(final Bitmap result) {
            if (result != null && !result.isRecycled()) {
                result.recycle();
            }
        }

    }

    @Override
    public Loader<Bitmap> onCreateLoader(int id, Bundle args) {
        return new PreviewRetriever(mContext, mVideoPath);
    }

    @Override
    public void onLoadFinished(final Loader<Bitmap> loader, final Bitmap bitmap) {
        if (bitmap != null) {
            mPreviewImage = new BitmapDrawable(mContext.getResources(), bitmap);
        }
    }

    @Override
    public void onLoaderReset(Loader<Bitmap> loader) {
    }

}
+12 −5
Original line number Diff line number Diff line
@@ -56,6 +56,10 @@ public class GestureSettings extends SettingsPreferenceFragment implements
    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 static final int PREF_ID_DOUBLE_TAP_POWER = 0;
    private static final int PREF_ID_DOUBLE_TWIST = 1;
    private static final int PREF_ID_PICK_UP_AND_NUDG = 2;
    private static final int PREF_ID_SWIPE_DOWN_FINGERPRINT = 3;

    private int mScrollPosition = -1;
    private List<GesturePreference> mPreferences;
@@ -71,7 +75,7 @@ public class GestureSettings extends SettingsPreferenceFragment implements
        if (isCameraDoubleTapPowerGestureAvailable(getResources())) {
            int cameraDisabled = Secure.getInt(
                    getContentResolver(), Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0);
            addPreference(PREF_KEY_DOUBLE_TAP_POWER, cameraDisabled == 0);
            addPreference(PREF_KEY_DOUBLE_TAP_POWER, cameraDisabled == 0, PREF_ID_DOUBLE_TAP_POWER);
        } else {
            removePreference(PREF_KEY_DOUBLE_TAP_POWER);
        }
@@ -79,14 +83,15 @@ public class GestureSettings extends SettingsPreferenceFragment implements
        // Ambient Display
        if (isDozeAvailable(context)) {
            int dozeEnabled = Secure.getInt(getContentResolver(), Secure.DOZE_ENABLED, 1);
            addPreference(PREF_KEY_PICK_UP_AND_NUDGE, dozeEnabled != 0);
            addPreference(PREF_KEY_PICK_UP_AND_NUDGE, dozeEnabled != 0, PREF_ID_DOUBLE_TWIST);
        } else {
            removePreference(PREF_KEY_PICK_UP_AND_NUDGE);
        }

        // Fingerprint slide for notifications
        if (isSystemUINavigationAvailable(context)) {
            addPreference(PREF_KEY_SWIPE_DOWN_FINGERPRINT, isSystemUINavigationEnabled(context));
            addPreference(PREF_KEY_SWIPE_DOWN_FINGERPRINT, isSystemUINavigationEnabled(context),
                    PREF_ID_PICK_UP_AND_NUDG);
        } else {
            removePreference(PREF_KEY_SWIPE_DOWN_FINGERPRINT);
        }
@@ -95,7 +100,8 @@ public class GestureSettings extends SettingsPreferenceFragment implements
        if (isDoubleTwistAvailable(context)) {
            int doubleTwistEnabled = Secure.getInt(
                    getContentResolver(), Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, 1);
            addPreference(PREF_KEY_DOUBLE_TWIST, doubleTwistEnabled != 0);
            addPreference(PREF_KEY_DOUBLE_TWIST, doubleTwistEnabled != 0,
                    PREF_ID_SWIPE_DOWN_FINGERPRINT);
        } else {
            removePreference(PREF_KEY_DOUBLE_TWIST);
        }
@@ -211,10 +217,11 @@ public class GestureSettings extends SettingsPreferenceFragment implements
        return false;
    }

    private void addPreference(String key, boolean enabled) {
    private void addPreference(String key, boolean enabled, int id) {
        GesturePreference preference = (GesturePreference) findPreference(key);
        preference.setChecked(enabled);
        preference.setOnPreferenceChangeListener(this);
        preference.loadPreview(getLoaderManager(), id);
        mPreferences.add(preference);
    }