1 /* Copyright 2012 Mozilla Foundation and Mozilla contributors 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef mozilla_dom_system_b2g_audiomanager_h__ 17 #define mozilla_dom_system_b2g_audiomanager_h__ 18 19 #include "mozilla/HalTypes.h" 20 #include "mozilla/Observer.h" 21 #include "mozilla/UniquePtr.h" 22 #include "nsAutoPtr.h" 23 #include "nsDataHashtable.h" 24 #include "nsIAudioManager.h" 25 #include "nsIObserver.h" 26 #include "android_audio/AudioSystem.h" 27 28 // {b2b51423-502d-4d77-89b3-7786b562b084} 29 #define NS_AUDIOMANAGER_CID {0x94f6fd70, 0x7615, 0x4af9, \ 30 {0x89, 0x10, 0xf9, 0x3c, 0x55, 0xe6, 0x62, 0xec}} 31 #define NS_AUDIOMANAGER_CONTRACTID "@mozilla.org/telephony/audiomanager;1" 32 33 class nsISettingsServiceLock; 34 35 namespace mozilla { 36 namespace hal { 37 class SwitchEvent; 38 typedef Observer<SwitchEvent> SwitchObserver; 39 } // namespace hal 40 41 namespace dom { 42 namespace gonk { 43 44 class VolumeInitCallback; 45 46 class AudioManager final : public nsIAudioManager 47 , public nsIObserver 48 { 49 public: 50 static already_AddRefed<AudioManager> GetInstance(); 51 52 NS_DECL_ISUPPORTS 53 NS_DECL_NSIAUDIOMANAGER 54 NS_DECL_NSIOBSERVER 55 56 // Validate whether the volume index is within the range 57 nsresult ValidateVolumeIndex(int32_t aStream, uint32_t aIndex) const; 58 59 // Called when android AudioFlinger in mediaserver is died 60 void HandleAudioFlingerDied(); 61 62 void HandleHeadphoneSwitchEvent(const hal::SwitchEvent& aEvent); 63 64 class VolumeStreamState { 65 public: 66 explicit VolumeStreamState(AudioManager& aManager, int32_t aStreamType); GetStreamType()67 int32_t GetStreamType() 68 { 69 return mStreamType; 70 } 71 bool IsDevicesChanged(bool aFromCache = true); 72 void ClearDevicesChanged(); GetLastDevices()73 uint32_t GetLastDevices() 74 { 75 return mLastDevices; 76 } 77 bool IsVolumeIndexesChanged(); 78 void ClearVolumeIndexesChanged(); 79 void InitStreamVolume(); 80 uint32_t GetMaxIndex(); 81 uint32_t GetDefaultIndex(); 82 uint32_t GetVolumeIndex(); 83 uint32_t GetVolumeIndex(uint32_t aDevice); 84 void ClearCurrentVolumeUpdated(); 85 // Set volume index to all active devices. 86 // Active devices are chosen by android AudioPolicyManager. 87 nsresult SetVolumeIndexToActiveDevices(uint32_t aIndex); 88 // Set volume index to all alias streams for device. Alias streams have same volume. 89 nsresult SetVolumeIndexToAliasStreams(uint32_t aIndex, uint32_t aDevice); 90 nsresult SetVolumeIndexToConsistentDeviceIfNeeded(uint32_t aIndex, uint32_t aDevice); 91 nsresult SetVolumeIndex(uint32_t aIndex, uint32_t aDevice, bool aUpdateCache = true); 92 // Restore volume index to all devices. Called when AudioFlinger is restarted. 93 void RestoreVolumeIndexToAllDevices(); 94 private: 95 AudioManager& mManager; 96 const int32_t mStreamType; 97 uint32_t mLastDevices; 98 bool mIsDevicesChanged; 99 bool mIsVolumeIndexesChanged; 100 nsDataHashtable<nsUint32HashKey, uint32_t> mVolumeIndexes; 101 }; 102 103 protected: 104 int32_t mPhoneState; 105 106 bool mIsVolumeInited; 107 108 // A bitwise variable for volume update of audio output devices, 109 // clear it after store the value into database. 110 uint32_t mAudioOutDevicesUpdated; 111 112 // Connected devices that are controlled by setDeviceConnectionState() 113 nsDataHashtable<nsUint32HashKey, nsCString> mConnectedDevices; 114 115 nsDataHashtable<nsUint32HashKey, uint32_t> mAudioDeviceTableIdMaps; 116 117 bool mSwitchDone; 118 119 #if defined(MOZ_B2G_BT) || ANDROID_VERSION >= 17 120 bool mBluetoothA2dpEnabled; 121 #endif 122 #ifdef MOZ_B2G_BT 123 bool mA2dpSwitchDone; 124 #endif 125 nsTArray<UniquePtr<VolumeStreamState> > mStreamStates; 126 uint32_t mLastChannelVolume[AUDIO_STREAM_CNT]; 127 128 bool IsFmOutConnected(); 129 130 nsresult SetStreamVolumeForDevice(int32_t aStream, 131 uint32_t aIndex, 132 uint32_t aDevice); 133 nsresult SetStreamVolumeIndex(int32_t aStream, uint32_t aIndex); 134 nsresult GetStreamVolumeIndex(int32_t aStream, uint32_t* aIndex); 135 136 void UpdateCachedActiveDevicesForStreams(); 137 uint32_t GetDevicesForStream(int32_t aStream, bool aFromCache = true); 138 uint32_t GetDeviceForStream(int32_t aStream); 139 // Choose one device as representative of active devices. 140 static uint32_t SelectDeviceFromDevices(uint32_t aOutDevices); 141 142 private: 143 nsAutoPtr<mozilla::hal::SwitchObserver> mObserver; 144 145 void HandleBluetoothStatusChanged(nsISupports* aSubject, 146 const char* aTopic, 147 const nsCString aAddress); 148 void HandleAudioChannelProcessChanged(); 149 150 // Append the audio output device to the volume setting string. 151 nsAutoCString AppendDeviceToVolumeSetting(const char* aName, 152 uint32_t aDevice); 153 154 // We store the volume setting in the database, these are related functions. 155 void InitVolumeFromDatabase(); 156 void MaybeUpdateVolumeSettingToDatabase(bool aForce = false); 157 158 // Promise functions. 159 void InitDeviceVolumeSucceeded(); 160 void InitDeviceVolumeFailed(const char* aError); 161 162 void AudioOutDeviceUpdated(uint32_t aDevice); 163 164 void UpdateHeadsetConnectionState(hal::SwitchState aState); 165 void UpdateDeviceConnectionState(bool aIsConnected, uint32_t aDevice, const nsCString& aDeviceName); 166 void SetAllDeviceConnectionStates(); 167 168 AudioManager(); 169 ~AudioManager(); 170 171 friend class VolumeInitCallback; 172 friend class VolumeStreamState; 173 friend class GonkAudioPortCallback; 174 }; 175 176 } /* namespace gonk */ 177 } /* namespace dom */ 178 } /* namespace mozilla */ 179 180 #endif // mozilla_dom_system_b2g_audiomanager_h__ 181