1 /* 2 ** 3 ** Copyright 2016, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 package com.android.commands.media; 19 20 import android.content.Context; 21 import android.media.AudioManager; 22 import android.media.AudioSystem; 23 import android.media.IAudioService; 24 import android.os.ServiceManager; 25 import android.util.AndroidException; 26 27 import com.android.internal.os.BaseCommand; 28 29 import java.io.BufferedReader; 30 import java.io.IOException; 31 import java.io.InputStreamReader; 32 import java.io.PrintStream; 33 import java.lang.ArrayIndexOutOfBoundsException; 34 35 /** 36 * Command line tool to exercise AudioService.setStreamVolume() 37 * and AudioService.adjustStreamVolume() 38 */ 39 public class VolumeCtrl { 40 41 private final static String TAG = "VolumeCtrl"; 42 43 // --stream affects --set, --adj or --get options. 44 // --show affects --set and --adj options. 45 // --get can be used with --set, --adj or by itself. 46 public final static String USAGE = new String( 47 "the options are as follows: \n" + 48 "\t\t--stream STREAM selects the stream to control, see AudioManager.STREAM_*\n" + 49 "\t\t controls AudioManager.STREAM_MUSIC if no stream is specified\n"+ 50 "\t\t--set INDEX sets the volume index value\n" + 51 "\t\t--adj DIRECTION adjusts the volume, use raise|same|lower for the direction\n" + 52 "\t\t--get outputs the current volume\n" + 53 "\t\t--show shows the UI during the volume change\n" + 54 "\texamples:\n" + 55 "\t\tadb shell media volume --show --stream 3 --set 11\n" + 56 "\t\tadb shell media volume --stream 0 --adj lower\n" + 57 "\t\tadb shell media volume --stream 3 --get\n" 58 ); 59 60 private final static int VOLUME_CONTROL_MODE_SET = 1; 61 private final static int VOLUME_CONTROL_MODE_ADJUST = 2; 62 63 private final static String ADJUST_LOWER = "lower"; 64 private final static String ADJUST_SAME = "same"; 65 private final static String ADJUST_RAISE = "raise"; 66 run(BaseCommand cmd)67 public static void run(BaseCommand cmd) throws Exception { 68 //---------------------------------------- 69 // Default parameters 70 int stream = AudioManager.STREAM_MUSIC; 71 int volIndex = 5; 72 int mode = 0; 73 int adjDir = AudioManager.ADJUST_RAISE; 74 boolean showUi = false; 75 boolean doGet = false; 76 77 //---------------------------------------- 78 // read options 79 String option; 80 String adjustment = null; 81 while ((option = cmd.nextOption()) != null) { 82 switch (option) { 83 case "--show": 84 showUi = true; 85 break; 86 case "--get": 87 doGet = true; 88 log(LOG_V, "will get volume"); 89 break; 90 case "--stream": 91 stream = Integer.decode(cmd.nextArgRequired()).intValue(); 92 log(LOG_V, "will control stream=" + stream + " (" + streamName(stream) + ")"); 93 break; 94 case "--set": 95 volIndex = Integer.decode(cmd.nextArgRequired()).intValue(); 96 mode = VOLUME_CONTROL_MODE_SET; 97 log(LOG_V, "will set volume to index=" + volIndex); 98 break; 99 case "--adj": 100 mode = VOLUME_CONTROL_MODE_ADJUST; 101 adjustment = cmd.nextArgRequired(); 102 log(LOG_V, "will adjust volume"); 103 break; 104 default: 105 throw new IllegalArgumentException("Unknown argument " + option); 106 } 107 } 108 109 //------------------------------ 110 // Read options: validation 111 if (mode == VOLUME_CONTROL_MODE_ADJUST) { 112 if (adjustment == null) { 113 cmd.showError("Error: no valid volume adjustment (null)"); 114 return; 115 } 116 switch (adjustment) { 117 case ADJUST_RAISE: adjDir = AudioManager.ADJUST_RAISE; break; 118 case ADJUST_SAME: adjDir = AudioManager.ADJUST_SAME; break; 119 case ADJUST_LOWER: adjDir = AudioManager.ADJUST_LOWER; break; 120 default: 121 cmd.showError("Error: no valid volume adjustment, was " + adjustment 122 + ", expected " + ADJUST_LOWER + "|" + ADJUST_SAME + "|" 123 + ADJUST_RAISE); 124 return; 125 } 126 } 127 128 //---------------------------------------- 129 // Test initialization 130 log(LOG_V, "Connecting to AudioService"); 131 IAudioService audioService = IAudioService.Stub.asInterface(ServiceManager.checkService( 132 Context.AUDIO_SERVICE)); 133 if (audioService == null) { 134 System.err.println(BaseCommand.NO_SYSTEM_ERROR_CODE); 135 throw new AndroidException( 136 "Can't connect to audio service; is the system running?"); 137 } 138 139 if (mode == VOLUME_CONTROL_MODE_SET) { 140 if ((volIndex > audioService.getStreamMaxVolume(stream)) 141 || (volIndex < audioService.getStreamMinVolume(stream))) { 142 cmd.showError(String.format("Error: invalid volume index %d for stream %d " 143 + "(should be in [%d..%d])", volIndex, stream, 144 audioService.getStreamMinVolume(stream), 145 audioService.getStreamMaxVolume(stream))); 146 return; 147 } 148 } 149 150 //---------------------------------------- 151 // Non-interactive test 152 final int flag = showUi? AudioManager.FLAG_SHOW_UI : 0; 153 final String pack = cmd.getClass().getPackage().getName(); 154 if (mode == VOLUME_CONTROL_MODE_SET) { 155 audioService.setStreamVolume(stream, volIndex, flag, pack/*callingPackage*/); 156 } else if (mode == VOLUME_CONTROL_MODE_ADJUST) { 157 audioService.adjustStreamVolume(stream, adjDir, flag, pack); 158 } 159 if (doGet) { 160 log(LOG_V, "volume is " + audioService.getStreamVolume(stream) + 161 " in range [" + audioService.getStreamMinVolume(stream) + 162 ".." + audioService.getStreamMaxVolume(stream) + "]"); 163 } 164 } 165 166 //-------------------------------------------- 167 // Utilities 168 169 static final String LOG_V = "[v]"; 170 static final String LOG_W = "[w]"; 171 static final String LOG_OK = "[ok]"; 172 log(String code, String msg)173 static void log(String code, String msg) { 174 System.out.println(code + " " + msg); 175 } 176 streamName(int stream)177 static String streamName(int stream) { 178 try { 179 return AudioSystem.STREAM_NAMES[stream]; 180 } catch (ArrayIndexOutOfBoundsException e) { 181 return "invalid stream"; 182 } 183 } 184 185 } 186