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.ArrayTestListAdapter; 20 import com.android.cts.verifier.PassFailButtons; 21 import com.android.cts.verifier.R; 22 import com.android.cts.verifier.TestListAdapter; 23 import com.android.cts.verifier.TestListAdapter.TestListItem; 24 25 import android.content.Intent; 26 import android.database.DataSetObserver; 27 import android.os.Bundle; 28 import android.widget.TextView; 29 30 import java.io.Serializable; 31 32 /** 33 * Tests for verifying the quality of streaming videos. Plays streams of different formats over 34 * different protocols for a short amount of time, after which users can mark Pass/Fail depending 35 * on the smoothness and subjective quality of the video. 36 */ 37 public class StreamingVideoActivity extends PassFailButtons.TestListActivity { 38 /** 39 * Simple storage class for stream information. 40 */ 41 static class Stream implements Serializable { 42 /** 43 * Human-readable name for the stream. 44 */ 45 public final String name; 46 47 /** 48 * Code name to append to the class name to identify this test. 49 */ 50 public final String code; 51 52 /** 53 * URI of the stream 54 */ 55 public final String uri; 56 57 public Stream(String name, String code, String uri) { 58 this.name = name; 59 this.code = code; 60 this.uri = uri; 61 } 62 63 @Override 64 public boolean equals(Object o) { 65 if (this == o) { 66 return true; 67 } else if (o == null || !(o instanceof Stream)) { 68 return false; 69 } else { 70 Stream stream = (Stream) o; 71 return name.equals(stream.name) 72 && code.equals(stream.code) 73 && uri.equals(stream.uri); 74 } 75 } 76 77 @Override 78 public int hashCode() { 79 return name.hashCode() ^ uri.hashCode() ^ code.hashCode(); 80 } 81 82 @Override 83 public String toString() { 84 return name; 85 } 86 } 87 88 private static final Stream[] RTSP_STREAMS = { 89 new Stream("H263 Video, AMR Audio", "rtsp_h263_amr", 90 "rtsp://v2.cache7.c.youtube.com/video.3gp?" 91 + "cid=0x271de9756065677e&fmt=13&user=android-device-test"), 92 new Stream("MPEG4 SP Video, AAC Audio", "rtsp_mpeg4_aac", 93 "rtsp://v2.cache7.c.youtube.com/video.3gp?" 94 + "cid=0x271de9756065677e&fmt=13&user=android-device-test"), 95 new Stream("H264 Base Video, AAC Audio", "rtsp_h264_aac", 96 "rtsp://v2.cache7.c.youtube.com/video.3gp?" 97 + "cid=0x271de9756065677e&fmt=13&user=android-device-test"), 98 }; 99 100 private static final Stream[] HTTP_STREAMS = { 101 new Stream("H263 Video, AMR Audio", "http_h263_amr", "http://v20.lscache8.c.youtube.com/" 102 + "videoplayback?id=271de9756065677e" 103 + "&itag=13&ip=0.0.0.0&ipbits=0&expire=999999999999999999" 104 + "&sparams=ip,ipbits,expire,ip,ipbits,expire,id,itag" 105 + "&signature=372FA4C532AA49D14EAF049BCDA66460EEE161E9" 106 + ".6D8BF096B73B7A68A7032CA8685053CFB498D30A" 107 + "&key=test_key1&user=android-device-test"), 108 new Stream("MPEG4 SP Video, AAC Audio", "http_mpeg4_aac", 109 "http://v20.lscache8.c.youtube.com/" 110 + "videoplayback?id=271de9756065677e" 111 + "&itag=17&ip=0.0.0.0&ipbits=0&expire=999999999999999999" 112 + "&sparams=ip,ipbits,expire,ip,ipbits,expire,id,itag" 113 + "&signature=3DCD3F79E045F95B6AF661765F046FB0440FF016" 114 + ".06A42661B3AF6BAF046F012549CC9BA34EBC80A9" 115 + "&key=test_key1&user=android-device-test"), 116 new Stream("H264 Base Video, AAC Audio", "http_h264_aac", 117 "http://v20.lscache8.c.youtube.com/" 118 + "videoplayback?id=271de9756065677e" 119 + "&itag=18&ip=0.0.0.0&ipbits=0&expire=999999999999999999" 120 + "&sparams=ip,ipbits,expire,ip,ipbits,expire,id,itag" 121 + "&signature=1219C2B07AF0638C27916307A6093C0E43CB894E" 122 + ".126B6B916BD57157782738AA7C03E59F21DBC168" 123 + "&key=test_key1&user=android-device-test"), 124 }; 125 126 @Override 127 protected void onCreate(Bundle savedInstanceState) { 128 super.onCreate(savedInstanceState); 129 setContentView(R.layout.pass_fail_list); 130 setPassFailButtonClickListeners(); 131 setInfoResources(R.string.streaming_video, R.string.streaming_video_info, -1); 132 133 TextView empty = (TextView) findViewById(android.R.id.empty); 134 empty.setText(R.string.sv_no_data); 135 136 getPassButton().setEnabled(false); 137 setTestListAdapter(getStreamAdapter()); 138 } 139 140 private TestListAdapter getStreamAdapter() { 141 ArrayTestListAdapter adapter = new ArrayTestListAdapter(this); 142 143 adapter.add(TestListItem.newCategory("RTSP")); 144 for (Stream stream : RTSP_STREAMS) { 145 addStreamToTests(adapter, stream); 146 } 147 148 adapter.add(TestListItem.newCategory("HTTP Progressive")); 149 for (Stream stream : HTTP_STREAMS) { 150 addStreamToTests(adapter, stream); 151 } 152 153 adapter.registerDataSetObserver(new DataSetObserver() { 154 @Override 155 public void onChanged() { 156 updatePassButton(); 157 } 158 }); 159 160 return adapter; 161 } 162 163 private void addStreamToTests(ArrayTestListAdapter streams, Stream stream) { 164 Intent i = new Intent(StreamingVideoActivity.this, PlayVideoActivity.class); 165 i.putExtra(PlayVideoActivity.EXTRA_STREAM, stream); 166 streams.add(TestListItem.newTest(stream.name, PlayVideoActivity.getTestId(stream.code), 167 i, null)); 168 } 169 170 private void updatePassButton() { 171 getPassButton().setEnabled(mAdapter.allTestsPassed()); 172 } 173 } 174