Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright 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 android.media.cts;
     18 
     19 import static org.junit.Assert.assertNotEquals;
     20 import static org.junit.Assert.fail;
     21 
     22 import android.app.Instrumentation;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.content.res.Resources;
     26 import android.media.AudioAttributes;
     27 import android.media.AudioManager;
     28 import android.media.session.MediaSession;
     29 import android.os.SystemClock;
     30 import android.view.KeyEvent;
     31 
     32 import androidx.test.InstrumentationRegistry;
     33 import androidx.test.filters.MediumTest;
     34 import androidx.test.rule.ActivityTestRule;
     35 import androidx.test.runner.AndroidJUnit4;
     36 
     37 import org.junit.After;
     38 import org.junit.Before;
     39 import org.junit.Rule;
     40 import org.junit.Test;
     41 import org.junit.runner.RunWith;
     42 
     43 import java.util.ArrayList;
     44 import java.util.HashMap;
     45 import java.util.List;
     46 import java.util.Map;
     47 
     48 /**
     49  * Test media activity which has called {@link Activity#setMediaController}.
     50  */
     51 @MediumTest
     52 @RunWith(AndroidJUnit4.class)
     53 public class MediaActivityTest {
     54     private static final String TAG = "MediaActivityTest";
     55     private static final int WAIT_TIME_MS = 500;
     56     private static final List<Integer> ALL_VOLUME_STREAMS = new ArrayList();
     57     static {
     58         ALL_VOLUME_STREAMS.add(AudioManager.STREAM_ACCESSIBILITY);
     59         ALL_VOLUME_STREAMS.add(AudioManager.STREAM_ALARM);
     60         ALL_VOLUME_STREAMS.add(AudioManager.STREAM_DTMF);
     61         ALL_VOLUME_STREAMS.add(AudioManager.STREAM_MUSIC);
     62         ALL_VOLUME_STREAMS.add(AudioManager.STREAM_NOTIFICATION);
     63         ALL_VOLUME_STREAMS.add(AudioManager.STREAM_RING);
     64         ALL_VOLUME_STREAMS.add(AudioManager.STREAM_SYSTEM);
     65         ALL_VOLUME_STREAMS.add(AudioManager.STREAM_VOICE_CALL);
     66     }
     67 
     68     private Instrumentation mInstrumentation;
     69     private Context mContext;
     70     private boolean mUseFixedVolume;
     71     private AudioManager mAudioManager;
     72     private Map<Integer, Integer> mStreamVolumeMap = new HashMap<>();
     73     private MediaSession mSession;
     74 
     75     @Rule
     76     public ActivityTestRule<MediaSessionTestActivity> mActivityRule =
     77             new ActivityTestRule<>(MediaSessionTestActivity.class, false, false);
     78 
     79     @Before
     80     public void setUp() throws Exception {
     81         mInstrumentation = InstrumentationRegistry.getInstrumentation();
     82         mContext = mInstrumentation.getContext();
     83         mUseFixedVolume = mContext.getResources().getBoolean(
     84                 Resources.getSystem().getIdentifier("config_useFixedVolume", "bool", "android"));
     85         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
     86 
     87         mStreamVolumeMap.clear();
     88         for (Integer stream : ALL_VOLUME_STREAMS) {
     89             mStreamVolumeMap.put(stream, mAudioManager.getStreamVolume(stream));
     90         }
     91 
     92         mSession = new MediaSession(mContext, TAG);
     93         mSession.setPlaybackToLocal(new AudioAttributes.Builder()
     94                 .setLegacyStreamType(AudioManager.STREAM_MUSIC).build());
     95 
     96         Intent intent = new Intent(Intent.ACTION_MAIN);
     97         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     98         intent.putExtra(MediaSessionTestActivity.KEY_SESSION_TOKEN, mSession.getSessionToken());
     99         mActivityRule.launchActivity(intent);
    100     }
    101 
    102     @After
    103     public void cleanUp() {
    104         if (mSession != null) {
    105             mSession.release();
    106             mSession = null;
    107         }
    108 
    109         for (int stream : mStreamVolumeMap.keySet()) {
    110             int volume = mStreamVolumeMap.get(stream);
    111             mAudioManager.setStreamVolume(stream, volume, 0);
    112         }
    113     }
    114 
    115     /**
    116      * Tests whether volume key changes volume with the session's stream.
    117      */
    118     @Test
    119     public void testVolumeKey_whileSessionAlive() throws InterruptedException {
    120         if (mUseFixedVolume) {
    121             return;
    122         }
    123 
    124         final int testStream = mSession.getController().getPlaybackInfo().getAudioAttributes()
    125                 .getVolumeControlStream();
    126         final int testKeyCode;
    127         if (mStreamVolumeMap.get(testStream) == mAudioManager.getStreamMinVolume(testStream)) {
    128             testKeyCode = KeyEvent.KEYCODE_VOLUME_UP;
    129         } else {
    130             testKeyCode = KeyEvent.KEYCODE_VOLUME_DOWN;
    131         }
    132 
    133         // The first event can be ignored and show volume panel instead. Use double tap.
    134         sendKeyEvent(testKeyCode);
    135         sendKeyEvent(testKeyCode);
    136 
    137         Thread.sleep(WAIT_TIME_MS);
    138         assertNotEquals((int) mStreamVolumeMap.get(testStream),
    139                 mAudioManager.getStreamVolume(testStream));
    140     }
    141 
    142     /**
    143      * Tests whether volume key changes volume even after the session is released.
    144      */
    145     @Test
    146     public void testVolumeKey_afterSessionReleased() throws InterruptedException {
    147         if (mUseFixedVolume) {
    148             return;
    149         }
    150 
    151         mSession.release();
    152 
    153         // The first event can be ignored and show volume panel instead. Use double tap.
    154         sendKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN);
    155         sendKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN);
    156 
    157         // We cannot know which stream is changed. Need to monitor all streams.
    158         Thread.sleep(WAIT_TIME_MS);
    159         for (int stream : mStreamVolumeMap.keySet()) {
    160             int volume = mStreamVolumeMap.get(stream);
    161             if (mAudioManager.getStreamVolume(stream) != volume) {
    162                 return;
    163             }
    164         }
    165 
    166         // Volume can be already zero for the target stream, so try again with the volume up.
    167         sendKeyEvent(KeyEvent.KEYCODE_VOLUME_UP);
    168         sendKeyEvent(KeyEvent.KEYCODE_VOLUME_UP);
    169 
    170         Thread.sleep(WAIT_TIME_MS);
    171         for (int stream : mStreamVolumeMap.keySet()) {
    172             int volume = mStreamVolumeMap.get(stream);
    173             if (mAudioManager.getStreamVolume(stream) != volume) {
    174                 return;
    175             }
    176         }
    177         fail("Volume keys were ignored");
    178     }
    179 
    180     private void sendKeyEvent(int keyCode) {
    181         final long downTime = SystemClock.uptimeMillis();
    182         final KeyEvent down = new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN, keyCode, 0);
    183         final long upTime = SystemClock.uptimeMillis();
    184         final KeyEvent up = new KeyEvent(downTime, upTime, KeyEvent.ACTION_UP, keyCode, 0);
    185         mInstrumentation.sendKeySync(down);
    186         mInstrumentation.sendKeySync(up);
    187     }
    188 }
    189