• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 com.android.server.media;
18 
19 import android.content.Context;
20 import android.media.AudioManager;
21 import android.media.AudioSystem;
22 import android.media.IAudioService;
23 import android.os.ServiceManager;
24 import android.util.AndroidException;
25 
26 import com.android.internal.os.BaseCommand;
27 
28 /**
29  * Command line tool to exercise AudioService.setStreamVolume()
30  *                           and AudioService.adjustStreamVolume()
31  */
32 public class VolumeCtrl {
33 
34     private static final String TAG = "VolumeCtrl";
35     private static final String LOG_V = "[V]";
36     private static final String LOG_E = "[E]";
37 
38     // --stream affects --set, --adj or --get options.
39     // --show affects --set and --adj options.
40     // --get can be used with --set, --adj or by itself.
41     public static final String USAGE = new String("the options are as follows: \n"
42             + "\t\t--stream STREAM selects the stream to control, see AudioManager.STREAM_*\n"
43             + "\t\t                controls AudioManager.STREAM_MUSIC if no stream is specified\n"
44             + "\t\t--set INDEX     sets the volume index value\n"
45             + "\t\t--adj DIRECTION adjusts the volume, use raise|same|lower for the direction\n"
46             + "\t\t--get           outputs the current volume\n"
47             + "\t\t--show          shows the UI during the volume change\n"
48             + "\texamples:\n"
49             + "\t\tadb shell media volume --show --stream 3 --set 11\n"
50             + "\t\tadb shell media volume --stream 0 --adj lower\n"
51             + "\t\tadb shell media volume --stream 3 --get\n"
52     );
53 
54     private static final int VOLUME_CONTROL_MODE_SET = 1;
55     private static final int VOLUME_CONTROL_MODE_ADJUST = 2;
56 
57     private static final String ADJUST_LOWER = "lower";
58     private static final String ADJUST_SAME = "same";
59     private static final String ADJUST_RAISE = "raise";
60 
61     /**
62      * Runs a given MediaShellCommand
63      */
run(MediaShellCommand cmd)64     public static void run(MediaShellCommand cmd) throws Exception {
65         //----------------------------------------
66         // Default parameters
67         int stream = AudioManager.STREAM_MUSIC;
68         int volIndex = 5;
69         int mode = 0;
70         int adjDir = AudioManager.ADJUST_RAISE;
71         boolean showUi = false;
72         boolean doGet = false;
73 
74         //----------------------------------------
75         // read options
76         String option;
77         String adjustment = null;
78         while ((option = cmd.getNextOption()) != null) {
79             switch (option) {
80                 case "--show":
81                     showUi = true;
82                     break;
83                 case "--get":
84                     doGet = true;
85                     cmd.log(LOG_V, "will get volume");
86                     break;
87                 case "--stream":
88                     stream = Integer.decode(cmd.getNextArgRequired()).intValue();
89                     cmd.log(LOG_V,
90                             "will control stream=" + stream + " (" + streamName(stream) + ")");
91                     break;
92                 case "--set":
93                     volIndex = Integer.decode(cmd.getNextArgRequired()).intValue();
94                     mode = VOLUME_CONTROL_MODE_SET;
95                     cmd.log(LOG_V, "will set volume to index=" + volIndex);
96                     break;
97                 case "--adj":
98                     mode = VOLUME_CONTROL_MODE_ADJUST;
99                     adjustment = cmd.getNextArgRequired();
100                     cmd.log(LOG_V, "will adjust volume");
101                     break;
102                 default:
103                     throw new IllegalArgumentException("Unknown argument " + option);
104             }
105         }
106 
107         //------------------------------
108         // Read options: validation
109         if (mode == VOLUME_CONTROL_MODE_ADJUST) {
110             if (adjustment == null) {
111                 cmd.showError("Error: no valid volume adjustment (null)");
112                 return;
113             }
114             switch (adjustment) {
115                 case ADJUST_RAISE: adjDir = AudioManager.ADJUST_RAISE; break;
116                 case ADJUST_SAME: adjDir = AudioManager.ADJUST_SAME; break;
117                 case ADJUST_LOWER: adjDir = AudioManager.ADJUST_LOWER; break;
118                 default:
119                     cmd.showError("Error: no valid volume adjustment, was " + adjustment
120                             + ", expected " + ADJUST_LOWER + "|" + ADJUST_SAME + "|"
121                             + ADJUST_RAISE);
122                     return;
123             }
124         }
125 
126         //----------------------------------------
127         // Test initialization
128         cmd.log(LOG_V, "Connecting to AudioService");
129         IAudioService audioService = IAudioService.Stub.asInterface(ServiceManager.checkService(
130                 Context.AUDIO_SERVICE));
131         if (audioService == null) {
132             cmd.log(LOG_E, BaseCommand.NO_SYSTEM_ERROR_CODE);
133             throw new AndroidException(
134                     "Can't connect to audio service; is the system running?");
135         }
136 
137         if (mode == VOLUME_CONTROL_MODE_SET) {
138             if ((volIndex > audioService.getStreamMaxVolume(stream))
139                     || (volIndex < audioService.getStreamMinVolume(stream))) {
140                 cmd.showError(String.format("Error: invalid volume index %d for stream %d "
141                                 + "(should be in [%d..%d])", volIndex, stream,
142                         audioService.getStreamMinVolume(stream),
143                         audioService.getStreamMaxVolume(stream)));
144                 return;
145             }
146         }
147 
148         //----------------------------------------
149         // Non-interactive test
150         final int flag = showUi ? AudioManager.FLAG_SHOW_UI : 0;
151         final String pack = cmd.getClass().getPackage().getName();
152         if (mode == VOLUME_CONTROL_MODE_SET) {
153             audioService.setStreamVolume(stream, volIndex, flag, pack/*callingPackage*/);
154         } else if (mode == VOLUME_CONTROL_MODE_ADJUST) {
155             audioService.adjustStreamVolume(stream, adjDir, flag, pack);
156         }
157         if (doGet) {
158             cmd.log(LOG_V, "volume is " + audioService.getStreamVolume(stream)
159                     + " in range [" + audioService.getStreamMinVolume(stream)
160                     + ".." + audioService.getStreamMaxVolume(stream) + "]");
161         }
162     }
163 
streamName(int stream)164     static String streamName(int stream) {
165         try {
166             return AudioSystem.STREAM_NAMES[stream];
167         } catch (ArrayIndexOutOfBoundsException e) {
168             return "invalid stream";
169         }
170     }
171 }
172