/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.android.exoplayer.audio; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.media.AudioFormat; import android.media.AudioManager; import java.util.Arrays; /** * Represents the set of audio formats a device is capable of playing back. */ @TargetApi(21) public final class AudioCapabilities { /** * Default to stereo PCM on SDK < 21 and when HDMI is unplugged. */ private static final AudioCapabilities DEFAULT_AUDIO_CAPABILITIES = new AudioCapabilities(new int[] {AudioFormat.ENCODING_PCM_16BIT}, 2); /** * Gets the current audio capabilities. Note that to be notified when audio capabilities change, * you can create an instance of {@link AudioCapabilitiesReceiver} and register a listener. * * @param context Context for receiving the initial broadcast. * @return Current audio capabilities for the device. */ @SuppressWarnings("InlinedApi") public static AudioCapabilities getCapabilities(Context context) { return getCapabilities( context.registerReceiver(null, new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG))); } @SuppressLint("InlinedApi") /* package */ static AudioCapabilities getCapabilities(Intent intent) { if (intent == null || intent.getIntExtra(AudioManager.EXTRA_AUDIO_PLUG_STATE, 0) == 0) { return DEFAULT_AUDIO_CAPABILITIES; } return new AudioCapabilities(intent.getIntArrayExtra(AudioManager.EXTRA_ENCODINGS), intent.getIntExtra(AudioManager.EXTRA_MAX_CHANNEL_COUNT, 0)); } private final int[] supportedEncodings; private final int maxChannelCount; /** * Constructs new audio capabilities based on a set of supported encodings and a maximum channel * count. * * @param supportedEncodings Supported audio encodings from {@link android.media.AudioFormat}'s * {@code ENCODING_*} constants. * @param maxChannelCount The maximum number of audio channels that can be played simultaneously. */ /* package */ AudioCapabilities(int[] supportedEncodings, int maxChannelCount) { if (supportedEncodings != null) { this.supportedEncodings = Arrays.copyOf(supportedEncodings, supportedEncodings.length); Arrays.sort(this.supportedEncodings); } else { this.supportedEncodings = new int[0]; } this.maxChannelCount = maxChannelCount; } /** * Returns whether this device supports playback of the specified audio {@code encoding}. * * @param encoding One of {@link android.media.AudioFormat}'s {@code ENCODING_*} constants. * @return Whether this device supports playback the specified audio {@code encoding}. */ public boolean supportsEncoding(int encoding) { return Arrays.binarySearch(supportedEncodings, encoding) >= 0; } /** Returns the maximum number of channels the device can play at the same time. */ public int getMaxChannelCount() { return maxChannelCount; } @Override public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof AudioCapabilities)) { return false; } AudioCapabilities audioCapabilities = (AudioCapabilities) other; return Arrays.equals(supportedEncodings, audioCapabilities.supportedEncodings) && maxChannelCount == audioCapabilities.maxChannelCount; } @Override public int hashCode() { return maxChannelCount + 31 * Arrays.hashCode(supportedEncodings); } @Override public String toString() { return "AudioCapabilities[maxChannelCount=" + maxChannelCount + ", supportedEncodings=" + Arrays.toString(supportedEncodings) + "]"; } }