1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.android.settings.gestures; 16 17 import android.content.ContentResolver; 18 import android.content.Context; 19 import android.content.res.TypedArray; 20 import android.graphics.SurfaceTexture; 21 import android.media.MediaPlayer; 22 import android.net.Uri; 23 import android.support.v14.preference.SwitchPreference; 24 import android.support.v7.preference.PreferenceViewHolder; 25 import android.view.View; 26 import android.view.Surface; 27 import android.view.TextureView; 28 import android.widget.ImageView; 29 import android.util.AttributeSet; 30 import android.util.Log; 31 32 import com.android.settings.R; 33 34 /** 35 * Preference item for a gesture with a switch to signify if it should be enabled. 36 * This shows the title and description of the gesture along with an animation showing how to do 37 * the gesture 38 */ 39 public final class GesturePreference extends SwitchPreference { 40 private static final String TAG = "GesturePreference"; 41 private final Context mContext; 42 43 private Uri mVideoPath; 44 private MediaPlayer mMediaPlayer; 45 private boolean mAnimationAvailable; 46 private boolean mVideoReady; 47 private boolean mScrolling; 48 private int mPreviewResource; 49 GesturePreference(Context context, AttributeSet attrs)50 public GesturePreference(Context context, AttributeSet attrs) { 51 super(context, attrs); 52 mContext = context; 53 TypedArray attributes = context.getTheme().obtainStyledAttributes( 54 attrs, 55 R.styleable.GesturePreference, 56 0, 0); 57 try { 58 int animation = attributes.getResourceId(R.styleable.GesturePreference_animation, 0); 59 mVideoPath = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) 60 .authority(context.getPackageName()) 61 .appendPath(String.valueOf(animation)) 62 .build(); 63 mMediaPlayer = MediaPlayer.create(mContext, mVideoPath); 64 if (mMediaPlayer != null && mMediaPlayer.getDuration() > 0) { 65 setLayoutResource(R.layout.gesture_preference); 66 67 mPreviewResource = attributes.getResourceId( 68 R.styleable.GesturePreference_preview, 0); 69 70 mMediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() { 71 @Override 72 public void onSeekComplete(MediaPlayer mp) { 73 mVideoReady = true; 74 } 75 }); 76 77 mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 78 @Override 79 public void onPrepared(MediaPlayer mediaPlayer) { 80 mediaPlayer.setLooping(true); 81 } 82 }); 83 mAnimationAvailable = true; 84 } 85 } catch (Exception e) { 86 Log.w(TAG, "Animation resource not found. Will not show animation."); 87 } finally { 88 attributes.recycle(); 89 } 90 } 91 92 @Override onBindViewHolder(PreferenceViewHolder holder)93 public void onBindViewHolder(PreferenceViewHolder holder) { 94 super.onBindViewHolder(holder); 95 96 if (!mAnimationAvailable) { 97 return; 98 } 99 100 final TextureView video = (TextureView) holder.findViewById(R.id.gesture_video); 101 final ImageView imageView = (ImageView) holder.findViewById(R.id.gesture_image); 102 imageView.setImageResource(mPreviewResource); 103 final ImageView playButton = (ImageView) holder.findViewById(R.id.gesture_play_button); 104 105 video.setOnClickListener(new View.OnClickListener() { 106 @Override 107 public void onClick(View v) { 108 if (mMediaPlayer != null) { 109 if (mMediaPlayer.isPlaying()) { 110 mMediaPlayer.pause(); 111 playButton.setVisibility(View.VISIBLE); 112 } else { 113 mMediaPlayer.start(); 114 playButton.setVisibility(View.GONE); 115 } 116 } 117 } 118 }); 119 120 video.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { 121 @Override 122 public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, 123 int height) { 124 if (mMediaPlayer != null) { 125 mMediaPlayer.setSurface(new Surface(surfaceTexture)); 126 mVideoReady = false; 127 mMediaPlayer.seekTo(0); 128 } 129 } 130 131 @Override 132 public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, 133 int height) { 134 } 135 136 @Override 137 public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { 138 imageView.setVisibility(View.VISIBLE); 139 return false; 140 } 141 142 @Override 143 public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { 144 if (mVideoReady && imageView.getVisibility() == View.VISIBLE) { 145 imageView.setVisibility(View.GONE); 146 } else if (mScrolling) { 147 mScrolling = false; 148 if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { 149 mMediaPlayer.pause(); 150 playButton.setVisibility(View.VISIBLE); 151 } 152 } 153 if (mMediaPlayer != null && !mMediaPlayer.isPlaying() && 154 playButton.getVisibility() != View.VISIBLE) { 155 playButton.setVisibility(View.VISIBLE); 156 } 157 } 158 }); 159 160 } 161 162 @Override onDetached()163 public void onDetached() { 164 if (mMediaPlayer != null) { 165 mMediaPlayer.stop(); 166 mMediaPlayer.reset(); 167 mMediaPlayer.release(); 168 } 169 super.onDetached(); 170 } 171 setScrolling(boolean scrolling)172 void setScrolling(boolean scrolling) { 173 mScrolling = scrolling; 174 } 175 onViewVisible()176 void onViewVisible() { 177 if (mVideoReady && mMediaPlayer != null && !mMediaPlayer.isPlaying()) { 178 mMediaPlayer.seekTo(0); 179 } 180 } 181 onViewInvisible()182 void onViewInvisible() { 183 if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { 184 mMediaPlayer.pause(); 185 } 186 } 187 188 } 189