Merge lp:~sylvain-pineau/checkbox/audio_settings_fixes into lp:checkbox

Proposed by Sylvain Pineau
Status: Merged
Approved by: Daniel Manrique
Approved revision: 2193
Merged at revision: 2194
Proposed branch: lp:~sylvain-pineau/checkbox/audio_settings_fixes
Merge into: lp:checkbox
Diff against target: 253 lines (+58/-38)
4 files modified
checkbox-old/checkbox/scripts/audio_settings.py (+45/-34)
checkbox-old/debian/changelog (+4/-0)
checkbox-old/jobs/audio.txt.in (+2/-2)
checkbox-old/scripts/gst_pipeline_test (+7/-2)
To merge this branch: bzr merge lp:~sylvain-pineau/checkbox/audio_settings_fixes
Reviewer Review Type Date Requested Status
Daniel Manrique (community) Approve
Review via email: mp+169425@code.launchpad.net

Commit message

checkbox-old/checkbox/scripts/audio-settings.py: fix the profile backup method

Description of the change

audio_settings: fix the profile backup method.

The previous method made the assumption that the saved card profile should
be applied to card #0 when restoring the settings.
It's wrong, especially for system using multiple ALSA cards.

The fix saves the current profile for all cards and use their symbolic
names to restore the profiles.

Profiles configuration is backed up using configparser.

To post a comment you must log in.
2193. By Sylvain Pineau

debian/changelog: Updated

Revision history for this message
Daniel Manrique (roadmr) wrote :

Looks good to me and the script seemed to work (though I don't know if my laptop shows different cards).

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'checkbox-old/checkbox/scripts/audio_settings.py' (properties changed: +x to -x)
2--- checkbox-old/checkbox/scripts/audio_settings.py 2013-06-12 20:19:05 +0000
3+++ checkbox-old/checkbox/scripts/audio_settings.py 2013-06-14 13:53:34 +0000
4@@ -17,6 +17,7 @@
5 # along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
6 #
7
8+import configparser
9 import logging
10 import os
11 import re
12@@ -138,33 +139,45 @@
13 (profile, error))
14
15
16-def get_current_profile_setting():
17- """Captures and Writes current audio profile setting"""
18- output_list = check_output(["pactl", "list"],
19- universal_newlines=True,
20- env=unlocalized_env())
21- active_profile = re.findall("Active\sProfile.*", output_list)[0]
22+def get_current_profiles_settings():
23+ """Captures and Writes current audio profiles settings"""
24+ pactl_list = check_output(
25+ ['pactl', 'list'], universal_newlines=True, env=unlocalized_env())
26+
27+ config = configparser.ConfigParser()
28+
29+ for match in re.finditer(
30+ "(?P<card_id>Card #\d+)\n\tName:\s+(?P<card_name>.*?)\n.*?"
31+ "Active\sProfile:\s+(?P<profile>.*?)\n", pactl_list, re.M | re.S
32+ ):
33+ config[match.group('card_id')] = {
34+ 'name': match.group('card_name'),
35+ 'profile': match.group('profile')
36+ }
37
38 try:
39- open("active_output", 'w').write(active_profile)
40+ with open('active_profiles', 'w') as active_profiles:
41+ config.write(active_profiles)
42 except IOError:
43- logging.error("Failed to save active output information: %s" %
44+ logging.error("Failed to save active profiles information: %s" %
45 sys.exc_info()[1])
46
47
48-def restore_profile_setting():
49+def restore_profiles_settings():
50+ config = configparser.ConfigParser()
51 try:
52- setting_info = open("active_output").read()
53- profile = setting_info.split("Active Profile:")[-1]
54- except (IOError, IndexError):
55- logging.error("Failed to retrieve previous profile information")
56- return
57+ config.read('active_profiles')
58+ except IOError:
59+ logging.error("Failed to retrieve previous profiles information")
60
61- try:
62- check_call(["pactl", "set-card-profile", "0", profile.strip()])
63- except CalledProcessError as error:
64- logging.error("Failed setting audio output to:%s: %s" %
65- (profile, error))
66+ for card in config.sections():
67+ try:
68+ check_call(["pactl", "set-card-profile", config[card]['name'],
69+ config[card]['profile']])
70+ except CalledProcessError as error:
71+ logging.error("Failed setting card <%s> profile to <%s>: %s" %
72+ (config[card]['name'],
73+ config[card]['profile'], error))
74
75
76 def move_sinks(name):
77@@ -185,7 +198,7 @@
78
79
80 def store_audio_settings(file):
81-
82+ logging.info("[ Saving audio settings ]".center(80, '='))
83 try:
84 settings_file = open(file, 'w')
85 except IOError:
86@@ -216,6 +229,7 @@
87
88 print("%s_volume: %s%%" % (type, str(volume)),
89 file=settings_file)
90+ settings_file.close()
91
92
93 def set_audio_settings(device, mute, volume):
94@@ -245,7 +259,7 @@
95
96 try:
97 check_call(["pactl",
98- "set-%s-mute" % type, name, str(mute)])
99+ "set-%s-mute" % type, name, str(int(mute))])
100 except:
101 logging.error("Failed to set mute for %s" % name)
102 sys.exit(1)
103@@ -259,8 +273,10 @@
104
105
106 def restore_audio_settings(file):
107+ logging.info("[ Restoring audio settings ]".center(80, '='))
108 try:
109- settings_file = open(file).read().split()
110+ with open(file) as f:
111+ settings_file = f.read().split()
112 except IOError:
113 logging.error("Unable to open existing settings file: %s" %
114 sys.exc_info()[1])
115@@ -281,33 +297,27 @@
116 "file is invalid")
117 return 1
118
119- logging.info(name)
120-
121 try:
122 with open(os.devnull, 'wb') as DEVNULL:
123 check_call(["pacmd", "set-default-%s" % type, name],
124 stdout=DEVNULL)
125 except CalledProcessError:
126- logging.error("Failed to set default %s" % name)
127+ logging.error("Failed to restore default %s" % name)
128 return 1
129
130 if type == "sink":
131 move_sinks(name)
132
133- logging.info(muted)
134-
135 try:
136 check_call(["pactl", "set-%s-mute" % type, name, muted])
137 except:
138- logging.error("Failed to set mute for %s" % name)
139+ logging.error("Failed to restore mute for %s" % name)
140 return 1
141
142- logging.info(volume)
143-
144 try:
145 check_call(["pactl", "set-%s-volume" % type, name, volume])
146 except:
147- logging.error("Failed to set volume for %s" % name)
148+ logging.error("Failed to restore volume for %s" % name)
149 return 1
150
151
152@@ -335,14 +345,15 @@
153 args = parser.parse_args()
154
155 if args.verbose:
156- logging.basicConfig(level=logging.INFO)
157+ logging.basicConfig(format='%(levelname)s:%(message)s',
158+ level=logging.INFO, stream=sys.stdout)
159 if args.action == "store":
160 if not args.file:
161 logging.error("No file specified to store audio settings!")
162 return 1
163
164 store_audio_settings(args.file)
165- get_current_profile_setting()
166+ get_current_profiles_settings()
167 elif args.action == "set":
168 if not args.device:
169 logging.error("No device specified to change settings of!")
170@@ -355,7 +366,7 @@
171 set_profile_hdmi()
172 set_audio_settings(args.device, args.mute, args.volume)
173 elif args.action == "restore":
174- if restore_profile_setting() or restore_audio_settings(args.file):
175+ if restore_profiles_settings() or restore_audio_settings(args.file):
176 return 1
177 else:
178 logging.error(args.action + "is not a valid action")
179
180=== modified file 'checkbox-old/checkbox/scripts/gputest_benchmark.py' (properties changed: +x to -x)
181=== modified file 'checkbox-old/debian/changelog'
182--- checkbox-old/debian/changelog 2013-06-14 12:53:36 +0000
183+++ checkbox-old/debian/changelog 2013-06-14 13:53:34 +0000
184@@ -39,6 +39,10 @@
185 * scripts/audio_settings: Use the new pactl parser to guess the right profile
186 to select for HDMI / DisplayPort tests.
187 * setup.py: Use setuptools find_packages(), more future proof.
188+ * checkbox/scripts/audio_settings.py: Save active profiles for all alsa cards
189+ (LP: #169425)
190+ * scripts/gst_pipeline_test: Use the logging module and the same config as
191+ audio_settings.
192
193 -- Brendan Donegan <brendan.donegan@canonical.com> Fri, 31 May 2013 16:04:42 +0100
194
195
196=== modified file 'checkbox-old/jobs/audio.txt.in'
197--- checkbox-old/jobs/audio.txt.in 2013-06-12 20:19:05 +0000
198+++ checkbox-old/jobs/audio.txt.in 2013-06-14 13:53:34 +0000
199@@ -33,7 +33,7 @@
200 package.name == 'gir1.2-gst-plugins-base-0.10' or package.name == 'gir1.2-gst-plugins-base-1.0'
201 package.name == 'pulseaudio-utils'
202 command:
203- audio_settings store --file=$CHECKBOX_DATA/pulseaudio_settings; audio_settings set --device=hdmi --volume=50 --verbose; gst_pipeline_test -t 2 --device hdmi 'audiotestsrc wave=sine freq=512 ! audioconvert ! audioresample ! autoaudiosink'; EXIT_CODE=$?; audio_settings restore --file=$CHECKBOX_DATA/pulseaudio_settings; exit $EXIT_CODE
204+ audio_settings store --verbose --file=$CHECKBOX_DATA/pulseaudio_settings; audio_settings set --verbose --device=hdmi --volume=50; gst_pipeline_test -t 2 --device hdmi 'audiotestsrc wave=sine freq=512 ! audioconvert ! audioresample ! autoaudiosink'; EXIT_CODE=$?; audio_settings restore --verbose --file=$CHECKBOX_DATA/pulseaudio_settings; exit $EXIT_CODE
205 _description:
206 PURPOSE:
207 HDMI audio interface verification
208@@ -51,7 +51,7 @@
209 package.name == 'gir1.2-gst-plugins-base-0.10' or package.name == 'gir1.2-gst-plugins-base-1.0'
210 package.name == 'pulseaudio-utils'
211 command:
212- audio_settings store --file=$CHECKBOX_DATA/pulseaudio_settings; audio_settings set --device=hdmi --volume=50 --verbose; gst_pipeline_test -t 2 --device hdmi 'audiotestsrc wave=sine freq=512 ! audioconvert ! audioresample ! autoaudiosink'; EXIT_CODE=$?; audio_settings restore --file=$CHECKBOX_DATA/pulseaudio_settings; exit $EXIT_CODE
213+ audio_settings store --verbose --file=$CHECKBOX_DATA/pulseaudio_settings; audio_settings set --verbose --device=hdmi --volume=50; gst_pipeline_test -t 2 --device hdmi 'audiotestsrc wave=sine freq=512 ! audioconvert ! audioresample ! autoaudiosink'; EXIT_CODE=$?; audio_settings restore --verbose --file=$CHECKBOX_DATA/pulseaudio_settings; exit $EXIT_CODE
214 _description:
215 PURPOSE:
216 DisplayPort audio interface verification
217
218=== modified file 'checkbox-old/scripts/gst_pipeline_test'
219--- checkbox-old/scripts/gst_pipeline_test 2013-06-12 20:29:28 +0000
220+++ checkbox-old/scripts/gst_pipeline_test 2013-06-14 13:53:34 +0000
221@@ -1,6 +1,7 @@
222 #!/usr/bin/env python3
223
224 from argparse import ArgumentParser
225+import logging
226 import re
227 import os
228 import sys
229@@ -21,11 +22,12 @@
230 sink = re.findall(".*name:\s<(.*%s.*)>" % device, sink_info)[0].lstrip()
231 status = data[data.index("\t" + device_name) + 3]
232 except (IndexError, ValueError):
233- print("Failed to find status for device: %s" % device, file=sys.stderr)
234+ logging.error("Failed to find status for device: %s" % device)
235 return False
236
237 os.environ['PULSE_SINK'] = sink
238- print("Device: %s %s" % (device_name.strip(), status.strip()))
239+ logging.info("[ Pulse sink ]".center(80, '='))
240+ logging.info("Device: %s %s" % (device_name.strip(), status.strip()))
241 return status
242
243
244@@ -41,6 +43,9 @@
245 help="Device to check for status")
246 args = parser.parse_args()
247
248+ logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO,
249+ stream=sys.stdout)
250+
251 exit_code = 0
252 if args.device:
253 if not check_state(args.device):

Subscribers

People subscribed via source and target branches