Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright © 2013 Mozilla Foundation |
michael@0 | 3 | * |
michael@0 | 4 | * This program is made available under an ISC-style license. See the |
michael@0 | 5 | * accompanying file LICENSE for details. |
michael@0 | 6 | */ |
michael@0 | 7 | #include <stddef.h> |
michael@0 | 8 | #if defined(HAVE_CONFIG_H) |
michael@0 | 9 | #include "config.h" |
michael@0 | 10 | #endif |
michael@0 | 11 | #include "cubeb/cubeb.h" |
michael@0 | 12 | #include "cubeb-internal.h" |
michael@0 | 13 | |
michael@0 | 14 | #define NELEMS(x) ((int) (sizeof(x) / sizeof(x[0]))) |
michael@0 | 15 | |
michael@0 | 16 | struct cubeb { |
michael@0 | 17 | struct cubeb_ops * ops; |
michael@0 | 18 | }; |
michael@0 | 19 | |
michael@0 | 20 | struct cubeb_stream { |
michael@0 | 21 | struct cubeb * context; |
michael@0 | 22 | }; |
michael@0 | 23 | |
michael@0 | 24 | #if defined(USE_PULSE) |
michael@0 | 25 | int pulse_init(cubeb ** context, char const * context_name); |
michael@0 | 26 | #endif |
michael@0 | 27 | #if defined(USE_JACK) |
michael@0 | 28 | int jack_init (cubeb ** context, char const * context_name); |
michael@0 | 29 | #endif |
michael@0 | 30 | #if defined(USE_ALSA) |
michael@0 | 31 | int alsa_init(cubeb ** context, char const * context_name); |
michael@0 | 32 | #endif |
michael@0 | 33 | #if defined(USE_AUDIOQUEUE) |
michael@0 | 34 | int audioqueue_init(cubeb ** context, char const * context_name); |
michael@0 | 35 | #endif |
michael@0 | 36 | #if defined(USE_AUDIOUNIT) |
michael@0 | 37 | int audiounit_init(cubeb ** context, char const * context_name); |
michael@0 | 38 | #endif |
michael@0 | 39 | #if defined(USE_DIRECTSOUND) |
michael@0 | 40 | int directsound_init(cubeb ** context, char const * context_name); |
michael@0 | 41 | #endif |
michael@0 | 42 | #if defined(USE_WINMM) |
michael@0 | 43 | int winmm_init(cubeb ** context, char const * context_name); |
michael@0 | 44 | #endif |
michael@0 | 45 | #if defined(USE_WASAPI) |
michael@0 | 46 | int wasapi_init(cubeb ** context, char const * context_name); |
michael@0 | 47 | #endif |
michael@0 | 48 | #if defined(USE_SNDIO) |
michael@0 | 49 | int sndio_init(cubeb ** context, char const * context_name); |
michael@0 | 50 | #endif |
michael@0 | 51 | #if defined(USE_OPENSL) |
michael@0 | 52 | int opensl_init(cubeb ** context, char const * context_name); |
michael@0 | 53 | #endif |
michael@0 | 54 | #if defined(USE_AUDIOTRACK) |
michael@0 | 55 | int audiotrack_init(cubeb ** context, char const * context_name); |
michael@0 | 56 | #endif |
michael@0 | 57 | |
michael@0 | 58 | int |
michael@0 | 59 | validate_stream_params(cubeb_stream_params stream_params) |
michael@0 | 60 | { |
michael@0 | 61 | if (stream_params.rate < 1000 || stream_params.rate > 192000 || |
michael@0 | 62 | stream_params.channels < 1 || stream_params.channels > 8) { |
michael@0 | 63 | return CUBEB_ERROR_INVALID_FORMAT; |
michael@0 | 64 | } |
michael@0 | 65 | |
michael@0 | 66 | switch (stream_params.format) { |
michael@0 | 67 | case CUBEB_SAMPLE_S16LE: |
michael@0 | 68 | case CUBEB_SAMPLE_S16BE: |
michael@0 | 69 | case CUBEB_SAMPLE_FLOAT32LE: |
michael@0 | 70 | case CUBEB_SAMPLE_FLOAT32BE: |
michael@0 | 71 | return CUBEB_OK; |
michael@0 | 72 | } |
michael@0 | 73 | |
michael@0 | 74 | return CUBEB_ERROR_INVALID_FORMAT; |
michael@0 | 75 | } |
michael@0 | 76 | |
michael@0 | 77 | int |
michael@0 | 78 | validate_latency(int latency) |
michael@0 | 79 | { |
michael@0 | 80 | if (latency < 1 || latency > 2000) { |
michael@0 | 81 | return CUBEB_ERROR_INVALID_PARAMETER; |
michael@0 | 82 | } |
michael@0 | 83 | return CUBEB_OK; |
michael@0 | 84 | } |
michael@0 | 85 | |
michael@0 | 86 | int |
michael@0 | 87 | cubeb_init(cubeb ** context, char const * context_name) |
michael@0 | 88 | { |
michael@0 | 89 | int (* init[])(cubeb **, char const *) = { |
michael@0 | 90 | #if defined(USE_PULSE) |
michael@0 | 91 | pulse_init, |
michael@0 | 92 | #endif |
michael@0 | 93 | #if defined(USE_JACK) |
michael@0 | 94 | jack_init, |
michael@0 | 95 | #endif |
michael@0 | 96 | #if defined(USE_ALSA) |
michael@0 | 97 | alsa_init, |
michael@0 | 98 | #endif |
michael@0 | 99 | #if defined(USE_AUDIOUNIT) |
michael@0 | 100 | audiounit_init, |
michael@0 | 101 | #endif |
michael@0 | 102 | #if defined(USE_AUDIOQUEUE) |
michael@0 | 103 | audioqueue_init, |
michael@0 | 104 | #endif |
michael@0 | 105 | #if defined(USE_WASAPI) |
michael@0 | 106 | wasapi_init, |
michael@0 | 107 | #endif |
michael@0 | 108 | #if defined(USE_WINMM) |
michael@0 | 109 | winmm_init, |
michael@0 | 110 | #endif |
michael@0 | 111 | #if defined(USE_DIRECTSOUND) |
michael@0 | 112 | directsound_init, |
michael@0 | 113 | #endif |
michael@0 | 114 | #if defined(USE_SNDIO) |
michael@0 | 115 | sndio_init, |
michael@0 | 116 | #endif |
michael@0 | 117 | #if defined(USE_OPENSL) |
michael@0 | 118 | opensl_init, |
michael@0 | 119 | #endif |
michael@0 | 120 | #if defined(USE_AUDIOTRACK) |
michael@0 | 121 | audiotrack_init, |
michael@0 | 122 | #endif |
michael@0 | 123 | }; |
michael@0 | 124 | int i; |
michael@0 | 125 | |
michael@0 | 126 | if (!context) { |
michael@0 | 127 | return CUBEB_ERROR_INVALID_PARAMETER; |
michael@0 | 128 | } |
michael@0 | 129 | |
michael@0 | 130 | for (i = 0; i < NELEMS(init); ++i) { |
michael@0 | 131 | if (init[i](context, context_name) == CUBEB_OK) { |
michael@0 | 132 | return CUBEB_OK; |
michael@0 | 133 | } |
michael@0 | 134 | } |
michael@0 | 135 | |
michael@0 | 136 | return CUBEB_ERROR; |
michael@0 | 137 | } |
michael@0 | 138 | |
michael@0 | 139 | char const * |
michael@0 | 140 | cubeb_get_backend_id(cubeb * context) |
michael@0 | 141 | { |
michael@0 | 142 | if (!context) { |
michael@0 | 143 | return NULL; |
michael@0 | 144 | } |
michael@0 | 145 | |
michael@0 | 146 | return context->ops->get_backend_id(context); |
michael@0 | 147 | } |
michael@0 | 148 | |
michael@0 | 149 | int |
michael@0 | 150 | cubeb_get_max_channel_count(cubeb * context, uint32_t * max_channels) |
michael@0 | 151 | { |
michael@0 | 152 | if (!context || !max_channels) { |
michael@0 | 153 | return CUBEB_ERROR_INVALID_PARAMETER; |
michael@0 | 154 | } |
michael@0 | 155 | |
michael@0 | 156 | return context->ops->get_max_channel_count(context, max_channels); |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | int |
michael@0 | 160 | cubeb_get_min_latency(cubeb * context, cubeb_stream_params params, uint32_t * latency_ms) |
michael@0 | 161 | { |
michael@0 | 162 | if (!context || !latency_ms) { |
michael@0 | 163 | return CUBEB_ERROR_INVALID_PARAMETER; |
michael@0 | 164 | } |
michael@0 | 165 | return context->ops->get_min_latency(context, params, latency_ms); |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | int |
michael@0 | 169 | cubeb_get_preferred_sample_rate(cubeb * context, uint32_t * rate) |
michael@0 | 170 | { |
michael@0 | 171 | if (!context || !rate) { |
michael@0 | 172 | return CUBEB_ERROR_INVALID_PARAMETER; |
michael@0 | 173 | } |
michael@0 | 174 | return context->ops->get_preferred_sample_rate(context, rate); |
michael@0 | 175 | } |
michael@0 | 176 | |
michael@0 | 177 | void |
michael@0 | 178 | cubeb_destroy(cubeb * context) |
michael@0 | 179 | { |
michael@0 | 180 | if (!context) { |
michael@0 | 181 | return; |
michael@0 | 182 | } |
michael@0 | 183 | |
michael@0 | 184 | context->ops->destroy(context); |
michael@0 | 185 | } |
michael@0 | 186 | |
michael@0 | 187 | int |
michael@0 | 188 | cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name, |
michael@0 | 189 | cubeb_stream_params stream_params, unsigned int latency, |
michael@0 | 190 | cubeb_data_callback data_callback, |
michael@0 | 191 | cubeb_state_callback state_callback, |
michael@0 | 192 | void * user_ptr) |
michael@0 | 193 | { |
michael@0 | 194 | int r; |
michael@0 | 195 | |
michael@0 | 196 | if (!context || !stream) { |
michael@0 | 197 | return CUBEB_ERROR_INVALID_PARAMETER; |
michael@0 | 198 | } |
michael@0 | 199 | |
michael@0 | 200 | if ((r = validate_stream_params(stream_params)) != CUBEB_OK || |
michael@0 | 201 | (r = validate_latency(latency)) != CUBEB_OK) { |
michael@0 | 202 | return r; |
michael@0 | 203 | } |
michael@0 | 204 | |
michael@0 | 205 | return context->ops->stream_init(context, stream, stream_name, |
michael@0 | 206 | stream_params, latency, |
michael@0 | 207 | data_callback, |
michael@0 | 208 | state_callback, |
michael@0 | 209 | user_ptr); |
michael@0 | 210 | } |
michael@0 | 211 | |
michael@0 | 212 | void |
michael@0 | 213 | cubeb_stream_destroy(cubeb_stream * stream) |
michael@0 | 214 | { |
michael@0 | 215 | if (!stream) { |
michael@0 | 216 | return; |
michael@0 | 217 | } |
michael@0 | 218 | |
michael@0 | 219 | stream->context->ops->stream_destroy(stream); |
michael@0 | 220 | } |
michael@0 | 221 | |
michael@0 | 222 | int |
michael@0 | 223 | cubeb_stream_start(cubeb_stream * stream) |
michael@0 | 224 | { |
michael@0 | 225 | if (!stream) { |
michael@0 | 226 | return CUBEB_ERROR_INVALID_PARAMETER; |
michael@0 | 227 | } |
michael@0 | 228 | |
michael@0 | 229 | return stream->context->ops->stream_start(stream); |
michael@0 | 230 | } |
michael@0 | 231 | |
michael@0 | 232 | int |
michael@0 | 233 | cubeb_stream_stop(cubeb_stream * stream) |
michael@0 | 234 | { |
michael@0 | 235 | if (!stream) { |
michael@0 | 236 | return CUBEB_ERROR_INVALID_PARAMETER; |
michael@0 | 237 | } |
michael@0 | 238 | |
michael@0 | 239 | return stream->context->ops->stream_stop(stream); |
michael@0 | 240 | } |
michael@0 | 241 | |
michael@0 | 242 | int |
michael@0 | 243 | cubeb_stream_get_position(cubeb_stream * stream, uint64_t * position) |
michael@0 | 244 | { |
michael@0 | 245 | if (!stream || !position) { |
michael@0 | 246 | return CUBEB_ERROR_INVALID_PARAMETER; |
michael@0 | 247 | } |
michael@0 | 248 | |
michael@0 | 249 | return stream->context->ops->stream_get_position(stream, position); |
michael@0 | 250 | } |
michael@0 | 251 | |
michael@0 | 252 | int |
michael@0 | 253 | cubeb_stream_get_latency(cubeb_stream * stream, uint32_t * latency) |
michael@0 | 254 | { |
michael@0 | 255 | if (!stream || !latency) { |
michael@0 | 256 | return CUBEB_ERROR_INVALID_PARAMETER; |
michael@0 | 257 | } |
michael@0 | 258 | |
michael@0 | 259 | return stream->context->ops->stream_get_latency(stream, latency); |
michael@0 | 260 | } |