1 /* 2 * Copyright (C) 2019 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.widget; 18 19 import android.content.ContentResolver; 20 import android.content.Context; 21 import android.graphics.SurfaceTexture; 22 import android.media.MediaPlayer; 23 import android.net.Uri; 24 import android.view.Surface; 25 import android.view.TextureView; 26 import android.view.View; 27 28 /** 29 * A {@link VideoPreference.AnimationController} containing a {@link 30 * MediaPlayer}. The controller is used by {@link VideoPreference} to display 31 * a mp4 resource. 32 */ 33 class MediaAnimationController implements VideoPreference.AnimationController { 34 private MediaPlayer mMediaPlayer; 35 private boolean mVideoReady; 36 private Surface mSurface; 37 MediaAnimationController(Context context, int videoId)38 MediaAnimationController(Context context, int videoId) { 39 final Uri videoPath = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) 40 .authority(context.getPackageName()) 41 .appendPath(String.valueOf(videoId)) 42 .build(); 43 mMediaPlayer = MediaPlayer.create(context, videoPath); 44 // when the playback res is invalid or others, MediaPlayer create may fail 45 // and return null, so need add the null judgement. 46 if (mMediaPlayer != null) { 47 mMediaPlayer.seekTo(0); 48 mMediaPlayer.setOnSeekCompleteListener(mp -> mVideoReady = true); 49 mMediaPlayer.setOnPreparedListener(mediaPlayer -> mediaPlayer.setLooping(true)); 50 } 51 } 52 53 @Override getVideoWidth()54 public int getVideoWidth() { 55 return mMediaPlayer.getVideoWidth(); 56 } 57 58 @Override getVideoHeight()59 public int getVideoHeight() { 60 return mMediaPlayer.getVideoHeight(); 61 } 62 63 @Override pause()64 public void pause() { 65 mMediaPlayer.pause(); 66 } 67 68 @Override start()69 public void start() { 70 mMediaPlayer.start(); 71 } 72 73 @Override isPlaying()74 public boolean isPlaying() { 75 return mMediaPlayer.isPlaying(); 76 } 77 78 @Override getDuration()79 public int getDuration() { 80 return mMediaPlayer.getDuration(); 81 } 82 83 @Override attachView(TextureView video, View preview, View playButton)84 public void attachView(TextureView video, View preview, View playButton) { 85 updateViewStates(preview, playButton); 86 video.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { 87 @Override 88 public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, 89 int height) { 90 setSurface(surfaceTexture); 91 } 92 93 @Override 94 public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, 95 int height) { 96 } 97 98 @Override 99 public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { 100 preview.setVisibility(View.VISIBLE); 101 mSurface = null; 102 return false; 103 } 104 105 @Override 106 public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { 107 setSurface(surfaceTexture); 108 if (mVideoReady) { 109 if (preview.getVisibility() == View.VISIBLE) { 110 preview.setVisibility(View.GONE); 111 } 112 if (mMediaPlayer != null 113 && !mMediaPlayer.isPlaying()) { 114 mMediaPlayer.start(); 115 playButton.setVisibility(View.GONE); 116 } 117 } 118 if (mMediaPlayer != null && !mMediaPlayer.isPlaying() 119 && playButton.getVisibility() != View.VISIBLE) { 120 playButton.setVisibility(View.VISIBLE); 121 } 122 } 123 }); 124 video.setOnClickListener(v -> updateViewStates(preview, playButton)); 125 } 126 127 @Override release()128 public void release() { 129 if (mMediaPlayer != null) { 130 mMediaPlayer.stop(); 131 mMediaPlayer.reset(); 132 mMediaPlayer.release(); 133 mMediaPlayer = null; 134 mVideoReady = false; 135 } 136 } 137 updateViewStates(View imageView, View playButton)138 private void updateViewStates(View imageView, View playButton) { 139 if (mMediaPlayer.isPlaying()) { 140 mMediaPlayer.pause(); 141 playButton.setVisibility(View.VISIBLE); 142 imageView.setVisibility(View.VISIBLE); 143 } else { 144 imageView.setVisibility(View.GONE); 145 playButton.setVisibility(View.GONE); 146 mMediaPlayer.start(); 147 } 148 } 149 setSurface(SurfaceTexture surfaceTexture)150 private void setSurface(SurfaceTexture surfaceTexture) { 151 if (mMediaPlayer != null && mSurface == null) { 152 mSurface = new Surface(surfaceTexture); 153 mMediaPlayer.setSurface(mSurface); 154 } 155 } 156 } 157