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