1 /* 2 * Copyright (C) 2011 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.cts.verifier.streamquality; 18 19 import com.android.cts.verifier.PassFailButtons; 20 import com.android.cts.verifier.R; 21 import com.android.cts.verifier.streamquality.StreamingVideoActivity.Stream; 22 23 import android.app.AlertDialog; 24 import android.app.Dialog; 25 import android.content.DialogInterface; 26 import android.content.DialogInterface.OnClickListener; 27 import android.graphics.Rect; 28 import android.media.MediaPlayer; 29 import android.media.MediaPlayer.OnErrorListener; 30 import android.media.MediaPlayer.OnPreparedListener; 31 import android.media.MediaPlayer.OnVideoSizeChangedListener; 32 import android.os.Bundle; 33 import android.os.Handler; 34 import android.util.Log; 35 import android.view.SurfaceHolder; 36 import android.view.SurfaceView; 37 import android.view.ViewGroup.LayoutParams; 38 import android.widget.FrameLayout; 39 40 import java.io.IOException; 41 42 /** 43 * Activity that plays a video and allows the user to select pass/fail after 5 seconds. 44 */ 45 public class PlayVideoActivity extends PassFailButtons.Activity 46 implements SurfaceHolder.Callback, OnErrorListener, OnPreparedListener, 47 OnVideoSizeChangedListener { 48 /** 49 * Intent extra defining the {@link Stream} information 50 */ 51 static final String EXTRA_STREAM = "com.android.cts.verifier.streamquality.EXTRA_STREAM"; 52 53 private static final String TAG = PlayVideoActivity.class.getName(); 54 private static final long ENABLE_PASS_DELAY = 5 * 1000; 55 56 private static final int FAIL_DIALOG_ID = 1; 57 58 private final Runnable enablePassButton = new Runnable() { 59 @Override public void run() { 60 setEnablePassButton(true); 61 } 62 }; 63 64 private Stream mStream; 65 private SurfaceHolder mHolder; 66 private SurfaceView mSurfaceView; 67 private FrameLayout mVideoFrame; 68 private MediaPlayer mPlayer; 69 private Handler mHandler = new Handler(); 70 private int mVideoWidth; 71 private int mVideoHeight; 72 73 @Override onCreate(Bundle savedInstanceState)74 protected void onCreate(Bundle savedInstanceState) { 75 super.onCreate(savedInstanceState); 76 setContentView(R.layout.sv_play); 77 setPassFailButtonClickListeners(); 78 79 setEnablePassButton(false); 80 81 mSurfaceView = (SurfaceView) findViewById(R.id.surface); 82 mVideoFrame = (FrameLayout) findViewById(R.id.videoframe); 83 mHolder = mSurfaceView.getHolder(); 84 mHolder.addCallback(this); 85 mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 86 87 mStream = (Stream) getIntent().getSerializableExtra(EXTRA_STREAM); 88 } 89 setEnablePassButton(boolean enable)90 private void setEnablePassButton(boolean enable) { 91 getPassButton().setEnabled(enable); 92 } 93 playVideo()94 private void playVideo() { 95 mPlayer = new MediaPlayer(); 96 mPlayer.setDisplay(mHolder); 97 mPlayer.setScreenOnWhilePlaying(true); 98 mPlayer.setOnVideoSizeChangedListener(this); 99 mPlayer.setOnErrorListener(this); 100 mPlayer.setOnPreparedListener(this); 101 try { 102 mPlayer.setDataSource(mStream.uri); 103 } catch (IOException e) { 104 Log.e(TAG, "Unable to play video, setDataSource failed", e); 105 showDialog(FAIL_DIALOG_ID); 106 return; 107 } 108 mPlayer.prepareAsync(); 109 } 110 111 @Override onCreateDialog(int id, Bundle args)112 public Dialog onCreateDialog(int id, Bundle args) { 113 switch (id) { 114 case FAIL_DIALOG_ID: 115 return new AlertDialog.Builder(this) 116 .setTitle(getString(R.string.sv_failed_title)) 117 .setMessage(getString(R.string.sv_failed_message)) 118 .setNegativeButton("Close", new OnClickListener() { 119 @Override 120 public void onClick(DialogInterface dialog, int which) { 121 setTestResultAndFinish(false); 122 } 123 }) 124 .show(); 125 default: 126 return super.onCreateDialog(id, args); 127 } 128 } 129 130 @Override 131 public String getTestId() { 132 return getTestId(mStream.code); 133 } 134 135 public static String getTestId(String code) { 136 return PlayVideoActivity.class.getName() + "_" + code; 137 } 138 139 @Override 140 protected void onPause() { 141 super.onPause(); 142 // This test must be completed in one session 143 mHandler.removeCallbacks(enablePassButton); 144 finish(); 145 } 146 147 @Override 148 protected void onDestroy() { 149 super.onDestroy(); 150 if (mPlayer != null) { 151 mPlayer.release(); 152 mPlayer = null; 153 } 154 } 155 156 @Override 157 public void surfaceCreated(SurfaceHolder holder) { 158 playVideo(); 159 } 160 161 @Override 162 public boolean onError(MediaPlayer mp, int what, int extra) { 163 Log.e(TAG, "Unable to play video, got onError with code " + what + ", extra " + extra); 164 showDialog(FAIL_DIALOG_ID); 165 return true; 166 } 167 168 @Override 169 public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { 170 if (width != 0 && height != 0) { 171 mVideoWidth = width; 172 mVideoHeight = height; 173 fillScreen(); 174 } 175 } 176 177 private void startVideoPlayback() { 178 mPlayer.start(); 179 180 // Enable Pass button after 5 seconds 181 mHandler.postDelayed(enablePassButton, ENABLE_PASS_DELAY); 182 } 183 184 @Override 185 public void onPrepared(MediaPlayer mp) { 186 startVideoPlayback(); 187 } 188 189 private void fillScreen() { 190 mHolder.setFixedSize(mVideoWidth, mVideoHeight); 191 Rect rect = new Rect(); 192 mVideoFrame.getDrawingRect(rect); 193 LayoutParams lp = mSurfaceView.getLayoutParams(); 194 float aspectRatio = ((float) mVideoWidth) / mVideoHeight; 195 if (rect.width() / aspectRatio <= rect.height()) { 196 lp.width = rect.width(); 197 lp.height = (int) (rect.width() / aspectRatio); 198 } else { 199 lp.width = (int) (rect.height() * aspectRatio); 200 lp.height = rect.height(); 201 } 202 mSurfaceView.setLayoutParams(lp); 203 } 204 205 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {} 206 @Override public void surfaceDestroyed(SurfaceHolder holder) {} 207 } 208