Home | History | Annotate | Download | only in media
      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 
     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 
    173     static void log(String code, String msg) {
    174         System.out.println(code + " " + msg);
    175     }
    176 
    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