1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.settings.fingerprint; 18 19 import android.content.ContentResolver; 20 import android.content.Context; 21 import android.content.res.Resources; 22 import android.graphics.SurfaceTexture; 23 import android.media.MediaPlayer; 24 import android.media.MediaPlayer.OnInfoListener; 25 import android.media.MediaPlayer.OnPreparedListener; 26 import android.net.Uri; 27 import android.support.annotation.VisibleForTesting; 28 import android.util.AttributeSet; 29 import android.view.Surface; 30 import android.view.TextureView; 31 import android.view.View; 32 33 import com.android.settings.R; 34 35 /** 36 * A view containing a VideoView for showing the user how to enroll a fingerprint 37 */ 38 public class FingerprintLocationAnimationVideoView extends TextureView 39 implements FingerprintFindSensorAnimation { 40 protected float mAspect = 1.0f; // initial guess until we know 41 protected MediaPlayer mMediaPlayer; 42 43 public FingerprintLocationAnimationVideoView(Context context, AttributeSet attrs) { 44 super(context, attrs); 45 } 46 47 @Override 48 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 49 // Width is driven by measurespec, height is derrived from aspect ratio 50 int originalWidth = MeasureSpec.getSize(widthMeasureSpec); 51 int height = Math.round(mAspect * originalWidth); 52 super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); 53 } 54 55 protected Uri getFingerprintLocationAnimation() { 56 return resourceEntryToUri(getContext(), R.raw.fingerprint_location_animation); 57 } 58 59 @Override 60 protected void onFinishInflate() { 61 super.onFinishInflate(); 62 setSurfaceTextureListener(new SurfaceTextureListener() { 63 private SurfaceTexture mTextureToDestroy = null; 64 65 @Override 66 public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, 67 int height) { 68 setVisibility(View.INVISIBLE); 69 Uri videoUri = getFingerprintLocationAnimation(); 70 if (mMediaPlayer != null) { 71 mMediaPlayer.release(); 72 } 73 if (mTextureToDestroy != null) { 74 mTextureToDestroy.release(); 75 mTextureToDestroy = null; 76 } 77 mMediaPlayer = createMediaPlayer(mContext, videoUri); 78 if (mMediaPlayer == null) { 79 // MediaPlayer.create() method can return null 80 return; 81 } 82 mMediaPlayer.setSurface(new Surface(surfaceTexture)); 83 mMediaPlayer.setOnPreparedListener(new OnPreparedListener() { 84 @Override 85 public void onPrepared(MediaPlayer mediaPlayer) { 86 mediaPlayer.setLooping(true); 87 } 88 }); 89 mMediaPlayer.setOnInfoListener(new OnInfoListener() { 90 @Override 91 public boolean onInfo(MediaPlayer mediaPlayer, int what, int extra) { 92 if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) { 93 // Keep the view hidden until video starts 94 setVisibility(View.VISIBLE); 95 } 96 return false; 97 } 98 }); 99 mAspect = (float) mMediaPlayer.getVideoHeight() / mMediaPlayer.getVideoWidth(); 100 requestLayout(); 101 startAnimation(); 102 } 103 104 @Override 105 public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, 106 int width, int height) { 107 } 108 109 @Override 110 public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { 111 mTextureToDestroy = surfaceTexture; 112 return false; 113 } 114 115 @Override 116 public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { 117 } 118 }); 119 } 120 121 @VisibleForTesting 122 MediaPlayer createMediaPlayer(Context context, Uri videoUri) { 123 return MediaPlayer.create(mContext, videoUri); 124 } 125 126 protected static Uri resourceEntryToUri (Context context, int id) { 127 Resources res = context.getResources(); 128 return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + 129 res.getResourcePackageName(id) + '/' + 130 res.getResourceTypeName(id) + '/' + 131 res.getResourceEntryName(id)); 132 } 133 134 @Override 135 public void startAnimation() { 136 if (mMediaPlayer != null && !mMediaPlayer.isPlaying()) { 137 mMediaPlayer.start(); 138 } 139 } 140 141 @Override 142 public void stopAnimation() { 143 if (mMediaPlayer != null) { 144 mMediaPlayer.stop(); 145 mMediaPlayer.release(); 146 mMediaPlayer = null; 147 } 148 } 149 150 @Override 151 public void pauseAnimation() { 152 if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { 153 mMediaPlayer.pause(); 154 } 155 } 156 157 } 158