1 /* 2 * Copyright (C) 2008 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 android.content.Context; 20 import android.content.pm.PackageManager; 21 import android.media.AudioAttributes; 22 import android.media.AudioManager; 23 import android.media.Ringtone; 24 import android.media.RingtoneManager; 25 import android.media.audiofx.HapticGenerator; 26 import android.net.Uri; 27 import android.os.Build; 28 import android.platform.test.annotations.AppModeFull; 29 import android.provider.Settings; 30 import android.test.InstrumentationTestCase; 31 import android.util.Log; 32 33 import com.android.compatibility.common.util.ApiLevelUtil; 34 35 @AppModeFull(reason = "TODO: evaluate and port to instant") 36 public class RingtoneTest extends InstrumentationTestCase { 37 private static final String TAG = "RingtoneTest"; 38 39 private Context mContext; 40 private Ringtone mRingtone; 41 private AudioManager mAudioManager; 42 private int mOriginalVolume; 43 private int mOriginalRingerMode; 44 private int mOriginalStreamType; 45 private Uri mDefaultRingUri; 46 47 private static boolean sIsAtLeastS = ApiLevelUtil.isAtLeast(Build.VERSION_CODES.S); 48 49 @Override setUp()50 protected void setUp() throws Exception { 51 super.setUp(); 52 enableAppOps(); 53 mContext = getInstrumentation().getContext(); 54 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 55 mRingtone = RingtoneManager.getRingtone(mContext, Settings.System.DEFAULT_RINGTONE_URI); 56 // backup ringer settings 57 mOriginalRingerMode = mAudioManager.getRingerMode(); 58 mOriginalVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_RING); 59 mOriginalStreamType = mRingtone.getStreamType(); 60 61 int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_RING); 62 63 if (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE) { 64 mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); 65 mAudioManager.setStreamVolume(AudioManager.STREAM_RING, maxVolume / 2, 66 AudioManager.FLAG_ALLOW_RINGER_MODES); 67 } else if (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL) { 68 mAudioManager.setStreamVolume(AudioManager.STREAM_RING, maxVolume / 2, 69 AudioManager.FLAG_ALLOW_RINGER_MODES); 70 } else { 71 try { 72 Utils.toggleNotificationPolicyAccess( 73 mContext.getPackageName(), getInstrumentation(), true); 74 // set ringer to a reasonable volume 75 mAudioManager.setStreamVolume(AudioManager.STREAM_RING, maxVolume / 2, 76 AudioManager.FLAG_ALLOW_RINGER_MODES); 77 // make sure that we are not in silent mode 78 mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); 79 } finally { 80 Utils.toggleNotificationPolicyAccess( 81 mContext.getPackageName(), getInstrumentation(), false); 82 } 83 } 84 85 mDefaultRingUri = RingtoneManager.getActualDefaultRingtoneUri(mContext, 86 RingtoneManager.TYPE_RINGTONE); 87 } 88 enableAppOps()89 private void enableAppOps() { 90 StringBuilder cmd = new StringBuilder(); 91 cmd.append("appops set "); 92 cmd.append(getInstrumentation().getContext().getPackageName()); 93 cmd.append(" android:write_settings allow"); 94 getInstrumentation().getUiAutomation().executeShellCommand(cmd.toString()); 95 try { 96 Thread.sleep(2200); 97 } catch (InterruptedException e) { 98 } 99 } 100 101 @Override tearDown()102 protected void tearDown() throws Exception { 103 // restore original settings 104 if (mRingtone != null) { 105 if (mRingtone.isPlaying()) mRingtone.stop(); 106 mRingtone.setStreamType(mOriginalStreamType); 107 } 108 if (mAudioManager != null) { 109 try { 110 Utils.toggleNotificationPolicyAccess( 111 mContext.getPackageName(), getInstrumentation(), true); 112 mAudioManager.setRingerMode(mOriginalRingerMode); 113 mAudioManager.setStreamVolume(AudioManager.STREAM_RING, mOriginalVolume, 114 AudioManager.FLAG_ALLOW_RINGER_MODES); 115 } finally { 116 Utils.toggleNotificationPolicyAccess( 117 mContext.getPackageName(), getInstrumentation(), false); 118 } 119 } 120 RingtoneManager.setActualDefaultRingtoneUri(mContext, RingtoneManager.TYPE_RINGTONE, 121 mDefaultRingUri); 122 super.tearDown(); 123 } 124 hasAudioOutput()125 private boolean hasAudioOutput() { 126 return getInstrumentation().getContext().getPackageManager() 127 .hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT); 128 } 129 isTV()130 private boolean isTV() { 131 return getInstrumentation().getContext().getPackageManager() 132 .hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY); 133 } 134 testRingtone()135 public void testRingtone() { 136 if (isTV()) { 137 return; 138 } 139 if (!hasAudioOutput()) { 140 Log.i(TAG, "Skipping testRingtone(): device doesn't have audio output."); 141 return; 142 } 143 144 assertNotNull(mRingtone.getTitle(mContext)); 145 assertTrue(mOriginalStreamType >= 0); 146 147 mRingtone.setStreamType(AudioManager.STREAM_MUSIC); 148 assertEquals(AudioManager.STREAM_MUSIC, mRingtone.getStreamType()); 149 mRingtone.setStreamType(AudioManager.STREAM_ALARM); 150 assertEquals(AudioManager.STREAM_ALARM, mRingtone.getStreamType()); 151 // make sure we play on STREAM_RING because we the volume on this stream is not 0 152 mRingtone.setStreamType(AudioManager.STREAM_RING); 153 assertEquals(AudioManager.STREAM_RING, mRingtone.getStreamType()); 154 155 // test both the "None" ringtone and an actual ringtone 156 RingtoneManager.setActualDefaultRingtoneUri(mContext, RingtoneManager.TYPE_RINGTONE, null); 157 mRingtone = RingtoneManager.getRingtone(mContext, Settings.System.DEFAULT_RINGTONE_URI); 158 assertTrue(mRingtone.getStreamType() == AudioManager.STREAM_RING); 159 mRingtone.play(); 160 assertFalse(mRingtone.isPlaying()); 161 162 Uri uri = RingtoneManager.getValidRingtoneUri(mContext); 163 assertNotNull("ringtone was unexpectedly null", uri); 164 RingtoneManager.setActualDefaultRingtoneUri(mContext, RingtoneManager.TYPE_RINGTONE, uri); 165 mRingtone = RingtoneManager.getRingtone(mContext, Settings.System.DEFAULT_RINGTONE_URI); 166 assertTrue(mRingtone.getStreamType() == AudioManager.STREAM_RING); 167 mRingtone.play(); 168 assertTrue("couldn't play ringtone " + uri, mRingtone.isPlaying()); 169 mRingtone.stop(); 170 assertFalse(mRingtone.isPlaying()); 171 } 172 testPlaybackProperties()173 public void testPlaybackProperties() { 174 if (isTV()) { 175 return; 176 } 177 if (!hasAudioOutput()) { 178 Log.i(TAG, "Skipping testRingtone(): device doesn't have audio output."); 179 return; 180 } 181 182 Uri uri = RingtoneManager.getValidRingtoneUri(mContext); 183 assertNotNull("ringtone was unexpectedly null", uri); 184 RingtoneManager.setActualDefaultRingtoneUri(mContext, RingtoneManager.TYPE_RINGTONE, uri); 185 assertNotNull(mRingtone.getTitle(mContext)); 186 final AudioAttributes ringtoneAa = new AudioAttributes.Builder() 187 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE). 188 build(); 189 mRingtone.setAudioAttributes(ringtoneAa); 190 assertEquals(ringtoneAa, mRingtone.getAudioAttributes()); 191 mRingtone.setLooping(true); 192 mRingtone.setVolume(0.5f); 193 if (sIsAtLeastS) { 194 assertEquals(HapticGenerator.isAvailable(), mRingtone.setHapticGeneratorEnabled(true)); 195 } 196 mRingtone.play(); 197 assertTrue("couldn't play ringtone " + uri, mRingtone.isPlaying()); 198 assertTrue(mRingtone.isLooping()); 199 if (sIsAtLeastS) { 200 assertEquals(HapticGenerator.isAvailable(), mRingtone.isHapticGeneratorEnabled()); 201 } 202 assertEquals("invalid ringtone player volume", 0.5f, mRingtone.getVolume()); 203 mRingtone.stop(); 204 assertFalse(mRingtone.isPlaying()); 205 } 206 } 207