1 /* 2 * Copyright (C) 2021 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.tunnelmode; 18 19 import android.app.AlertDialog; 20 import android.content.ContentResolver; 21 import android.content.DialogInterface; 22 import android.content.res.Resources; 23 import android.media.AudioManager; 24 import android.media.cts.MediaCodecTunneledPlayer; 25 import android.net.Uri; 26 import android.os.Bundle; 27 import android.os.Handler; 28 import android.os.Looper; 29 import android.util.Log; 30 import android.view.SurfaceHolder; 31 import android.view.SurfaceView; 32 import android.view.View; 33 import android.widget.Button; 34 import android.widget.TextView; 35 36 import com.android.cts.verifier.PassFailButtons; 37 import com.android.cts.verifier.R; 38 39 /** 40 * Test for verifying that the Volume level changes are reflected both with and without tunnel mode 41 * playback for PCM audio 42 */ 43 public class VolumeLevelChangesActivity extends PassFailButtons.Activity { 44 45 private static final String TAG = VolumeLevelChangesActivity.class.getSimpleName(); 46 47 private SurfaceHolder mHolder; 48 private int mAudioSessionId = 0; 49 private MediaCodecTunneledPlayer mPlayer; 50 private Handler mHandler; 51 52 private Integer mCurrentStep; 53 private static final int STEP_ADJUST_VOLUME_FOR_NON_TUNNELED_PLAYBACK = 1; 54 private static final int STEP_ASK_USER_ABOUT_TUNNEL_VOLUME = 2; 55 private static final int STEP_ADJUST_VOLUME_FOR_TUNNELED_PLAYBACK = 3; 56 private static final int STEP_ASK_USER_ABOUT_NON_TUNNEL_VOLUME = 4; 57 private static final int STEP_DONE = 5; 58 59 @Override onCreate(Bundle savedInstanceState)60 protected void onCreate(Bundle savedInstanceState) { 61 super.onCreate(savedInstanceState); 62 setContentView(R.layout.tunnel_mode_volume_changes); 63 enablePassButton(false); 64 65 AudioManager am = getApplicationContext().getSystemService(AudioManager.class); 66 mAudioSessionId = am.generateAudioSessionId(); 67 68 SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surface); 69 mHolder = surfaceView.getHolder(); 70 mHolder.addCallback(new SurfaceHolder.Callback() { 71 public void surfaceCreated(SurfaceHolder holder) { 72 mCurrentStep = STEP_ADJUST_VOLUME_FOR_NON_TUNNELED_PLAYBACK; 73 process(mCurrentStep); 74 } 75 76 public void surfaceChanged( 77 SurfaceHolder holder, int format, int width, int height) { 78 } 79 80 public void surfaceDestroyed(SurfaceHolder holder) { 81 } 82 }); 83 84 mHandler = new Handler(Looper.getMainLooper()); 85 } 86 getAsResourceUri(int resId)87 private Uri getAsResourceUri(int resId) { 88 Resources res = getResources(); 89 return new Uri.Builder() 90 .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) 91 .authority(res.getResourcePackageName(resId)) 92 .appendPath(res.getResourceTypeName(resId)) 93 .appendPath(res.getResourceEntryName(resId)) 94 .build(); 95 } 96 enablePassButton(boolean enable)97 private void enablePassButton(boolean enable) { 98 getPassButton().setEnabled(enable); 99 } 100 101 /** Handler for ok button */ onOkClicked(View view)102 public void onOkClicked(View view) { 103 mCurrentStep = getNextStep(mCurrentStep); 104 process(mCurrentStep); 105 } 106 process(int step)107 private void process(int step) { 108 switch (step) { 109 case STEP_ADJUST_VOLUME_FOR_NON_TUNNELED_PLAYBACK: { 110 restartVideo(/* shouldUseTunnelMode= */false); 111 112 TextView instruction = findViewById(R.id.instruction); 113 instruction.setText(R.string.increase_volume_level); 114 115 Button okButton = findViewById(R.id.okButton); 116 okButton.setText(R.string.ok_button_volume_level); 117 118 Button cancelButton = findViewById(R.id.cancelButton); 119 cancelButton.setVisibility(View.INVISIBLE); 120 121 break; 122 } 123 case STEP_ASK_USER_ABOUT_TUNNEL_VOLUME: 124 case STEP_ASK_USER_ABOUT_NON_TUNNEL_VOLUME: { 125 boolean shouldUseTunnelMode = (step == STEP_ASK_USER_ABOUT_TUNNEL_VOLUME); 126 restartVideo(shouldUseTunnelMode); 127 128 TextView instruction = findViewById(R.id.instruction); 129 instruction.setText(R.string.is_same_volume); 130 131 Button okButton = findViewById(R.id.okButton); 132 okButton.setText(R.string.yes_button_volume_level); 133 134 Button cancelButton = findViewById(R.id.cancelButton); 135 cancelButton.setText(R.string.no_button_volume_level); 136 cancelButton.setVisibility(View.VISIBLE); 137 138 break; 139 } 140 case STEP_ADJUST_VOLUME_FOR_TUNNELED_PLAYBACK: { 141 TextView instruction = findViewById(R.id.instruction); 142 instruction.setText(R.string.decrease_volume_level); 143 144 Button okButton = findViewById(R.id.okButton); 145 okButton.setText(R.string.ok_button_volume_level); 146 147 Button cancelButton = findViewById(R.id.cancelButton); 148 cancelButton.setVisibility(View.INVISIBLE); 149 150 break; 151 } 152 case STEP_DONE: { 153 stopVideo(); 154 setTestResultAndFinish(true); 155 break; 156 } 157 } 158 } 159 getNextStep(int step)160 private int getNextStep(int step) { 161 switch (step) { 162 case STEP_ADJUST_VOLUME_FOR_NON_TUNNELED_PLAYBACK: 163 return STEP_ASK_USER_ABOUT_TUNNEL_VOLUME; 164 case STEP_ASK_USER_ABOUT_TUNNEL_VOLUME: 165 return STEP_ADJUST_VOLUME_FOR_TUNNELED_PLAYBACK; 166 case STEP_ADJUST_VOLUME_FOR_TUNNELED_PLAYBACK: 167 return STEP_ASK_USER_ABOUT_NON_TUNNEL_VOLUME; 168 case STEP_ASK_USER_ABOUT_NON_TUNNEL_VOLUME: 169 return STEP_DONE; 170 default: 171 return -1; 172 } 173 } 174 restartVideo(boolean shouldUseTunnelMode)175 private void restartVideo(boolean shouldUseTunnelMode) { 176 if (mPlayer != null) { 177 stopVideo(); 178 } 179 mPlayer = new MediaCodecTunneledPlayer(this, mHolder, shouldUseTunnelMode, mAudioSessionId); 180 181 Uri mediaUri = getAsResourceUri( 182 R.raw.bbb_s4_1280x720_vp9_0p31_4mbps_30fps_stereo_128kbps_48000hz); 183 mPlayer.setVideoDataSource(mediaUri, null); 184 mPlayer.setAudioDataSource(mediaUri, null); 185 186 playVideo(); 187 } 188 189 /** Handler for cancel button */ onCancelClicked(View view)190 public void onCancelClicked(View view) { 191 int dialogMessage = 192 (mCurrentStep == STEP_ASK_USER_ABOUT_TUNNEL_VOLUME) 193 ? R.string.volume_level_changes_failure_non_tunnel_to_tunnel 194 : R.string.volume_level_changes_failure_tunnel_to_non_tunnel; 195 196 new AlertDialog.Builder(view.getContext()) 197 .setMessage(dialogMessage) 198 .setCancelable(true) 199 .setPositiveButton(R.string.ok_button_volume_level, 200 new DialogInterface.OnClickListener() { 201 public void onClick(DialogInterface dialog, int id) { 202 stopVideo(); 203 setTestResultAndFinish(false); 204 dialog.cancel(); 205 } 206 }) 207 .show(); 208 } 209 playVideo()210 private void playVideo() { 211 try { 212 mPlayer.prepare(); 213 mPlayer.setLoopEnabled(true); 214 mPlayer.startCodec(); 215 mPlayer.play(); 216 } catch (Exception e) { 217 Log.d(TAG, "Could not play the video.", e); 218 } 219 } 220 stopVideo()221 private void stopVideo() { 222 mPlayer.pause(); 223 mPlayer.reset(); 224 } 225 226 } 227