1 // Copyright 2020 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 use std::any::Any;
5 use std::error;
6 use std::fmt;
7 use std::io;
8 use std::num::ParseIntError;
9 use std::path::PathBuf;
10 use std::sync::PoisonError;
11 use std::time;
12 
13 use remain::sorted;
14 
15 use crate::CalibData;
16 
17 pub type Result<T> = std::result::Result<T, Error>;
18 
19 #[sorted]
20 #[derive(Debug)]
21 pub enum Error {
22     AlsaCardError(cros_alsa::CardError),
23     AlsaControlError(cros_alsa::ControlError),
24     AlsaControlTLVError(cros_alsa::ControlTLVError),
25     CalibrationTimeout,
26     CrasClientFailed(libcras::Error),
27     DeserializationFailed(String, serde_yaml::Error),
28     DSMParamUpdateFailed(cros_alsa::ControlTLVError),
29     FileIOFailed(PathBuf, io::Error),
30     InternalSpeakerNotFound,
31     InvalidDatastore,
32     InvalidDSMParam,
33     InvalidShutDownTime,
34     InvalidTemperature(f32),
35     LargeCalibrationDiff(CalibData),
36     MissingDSMParam,
37     MutexPoisonError,
38     NewPlayStreamFailed(libcras::BoxError),
39     NextPlaybackBufferFailed(libcras::BoxError),
40     PlaybackFailed(io::Error),
41     SerdeError(PathBuf, serde_yaml::Error),
42     StartPlaybackTimeout,
43     SystemTimeError(time::SystemTimeError),
44     UnsupportedSoundCard(String),
45     VPDParseFailed(String, ParseIntError),
46     WorkerPanics(Box<dyn Any + Send + 'static>),
47     ZeroPlayerIsNotRunning,
48     ZeroPlayerIsRunning,
49 }
50 
51 impl PartialEq for Error {
52     // Implement eq for more Error when needed.
eq(&self, other: &Error) -> bool53     fn eq(&self, other: &Error) -> bool {
54         match (self, other) {
55             (Error::InvalidDSMParam, Error::InvalidDSMParam) => true,
56             _ => false,
57         }
58     }
59 }
60 
61 impl From<cros_alsa::CardError> for Error {
from(err: cros_alsa::CardError) -> Error62     fn from(err: cros_alsa::CardError) -> Error {
63         Error::AlsaCardError(err)
64     }
65 }
66 
67 impl From<cros_alsa::ControlError> for Error {
from(err: cros_alsa::ControlError) -> Error68     fn from(err: cros_alsa::ControlError) -> Error {
69         Error::AlsaControlError(err)
70     }
71 }
72 
73 impl From<cros_alsa::ControlTLVError> for Error {
from(err: cros_alsa::ControlTLVError) -> Error74     fn from(err: cros_alsa::ControlTLVError) -> Error {
75         Error::AlsaControlTLVError(err)
76     }
77 }
78 
79 impl<T> From<PoisonError<T>> for Error {
from(_: PoisonError<T>) -> Error80     fn from(_: PoisonError<T>) -> Error {
81         Error::MutexPoisonError
82     }
83 }
84 
85 impl error::Error for Error {}
86 
87 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result88     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89         use Error::*;
90         match self {
91             AlsaCardError(e) => write!(f, "AlsaCardError: {}", e),
92             AlsaControlError(e) => write!(f, "AlsaControlError: {}", e),
93             AlsaControlTLVError(e) => write!(f, "AlsaControlTLVError: {}", e),
94             CalibrationTimeout => write!(f, "calibration is not finished in time"),
95             DSMParamUpdateFailed(e) => write!(f, "failed to update DsmParam, err: {}", e),
96             CrasClientFailed(e) => write!(f, "failed to create cras client: {}", e),
97             DeserializationFailed(file_path, e) => {
98                 write!(f, "failed to parse {}: {}", file_path, e)
99             }
100             FileIOFailed(file_path, e) => write!(f, "{:#?}: {}", file_path, e),
101             InvalidShutDownTime => write!(f, "invalid shutdown time"),
102             InternalSpeakerNotFound => write!(f, "internal speaker is not found in cras"),
103             InvalidTemperature(temp) => write!(
104                 f,
105                 "invalid calibration temperature: {}, and there is no datastore",
106                 temp
107             ),
108             InvalidDatastore => write!(f, "invalid datastore format"),
109             InvalidDSMParam => write!(f, "invalid dsm param from kcontrol"),
110             LargeCalibrationDiff(calib) => {
111                 write!(f, "calibration difference is too large, calib: {:?}", calib)
112             }
113             MissingDSMParam => write!(f, "missing dsm_param.bin"),
114             MutexPoisonError => write!(f, "mutex is poisoned"),
115             NewPlayStreamFailed(e) => write!(f, "{}", e),
116             NextPlaybackBufferFailed(e) => write!(f, "{}", e),
117             PlaybackFailed(e) => write!(f, "{}", e),
118             SerdeError(file_path, e) => write!(f, "{:?}: {}", file_path, e),
119             StartPlaybackTimeout => write!(f, "playback is not started in time"),
120             SystemTimeError(e) => write!(f, "{}", e),
121             UnsupportedSoundCard(name) => write!(f, "unsupported sound card: {}", name),
122             VPDParseFailed(file_path, e) => write!(f, "failed to parse vpd {}: {}", file_path, e),
123             WorkerPanics(e) => write!(f, "run_play_zero_worker panics: {:#?}", e),
124             ZeroPlayerIsNotRunning => write!(f, "zero player is not running"),
125             ZeroPlayerIsRunning => write!(f, "zero player is running"),
126         }
127     }
128 }
129