@@ -462,7 +462,21 @@ public AudioService(Context context) {
462462 mVolumePanel = new VolumePanel (context , this );
463463 mMode = AudioSystem .MODE_NORMAL ;
464464 mForcedUseForComm = AudioSystem .FORCE_NONE ;
465+
465466 createAudioSystemThread ();
467+
468+ boolean cameraSoundForced = mContext .getResources ().getBoolean (
469+ com .android .internal .R .bool .config_camera_sound_forced );
470+ mCameraSoundForced = new Boolean (cameraSoundForced );
471+ sendMsg (mAudioHandler ,
472+ MSG_SET_FORCE_USE ,
473+ SENDMSG_QUEUE ,
474+ AudioSystem .FOR_SYSTEM ,
475+ cameraSoundForced ?
476+ AudioSystem .FORCE_SYSTEM_ENFORCED : AudioSystem .FORCE_NONE ,
477+ null ,
478+ 0 );
479+
466480 readPersistedSettings ();
467481 mSettingsObserver = new SettingsObserver ();
468482 updateStreamVolumeAlias (false /*updateVolumes*/ );
@@ -585,6 +599,8 @@ private void dumpStreamStates(PrintWriter pw) {
585599 mStreamStates [i ].dump (pw );
586600 pw .println ("" );
587601 }
602+ pw .print ("\n - mute affected streams = 0x" );
603+ pw .println (Integer .toHexString (mMuteAffectedStreams ));
588604 }
589605
590606
@@ -634,35 +650,44 @@ private void readPersistedSettings() {
634650 }
635651 synchronized (mSettingsLock ) {
636652 mRingerMode = ringerMode ;
637- }
638653
639- // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting
640- // are still needed while setVibrateSetting() and getVibrateSetting() are being deprecated.
641- mVibrateSetting = getValueForVibrateSetting (0 ,
642- AudioManager .VIBRATE_TYPE_NOTIFICATION ,
643- mHasVibrator ? AudioManager .VIBRATE_SETTING_ONLY_SILENT
644- : AudioManager .VIBRATE_SETTING_OFF );
645- mVibrateSetting = getValueForVibrateSetting (mVibrateSetting ,
646- AudioManager .VIBRATE_TYPE_RINGER ,
647- mHasVibrator ? AudioManager .VIBRATE_SETTING_ONLY_SILENT
648- : AudioManager .VIBRATE_SETTING_OFF );
649-
650- // make sure settings for ringer mode are consistent with device type: non voice capable
651- // devices (tablets) include media stream in silent mode whereas phones don't.
652- mRingerModeAffectedStreams = Settings .System .getIntForUser (cr ,
653- Settings .System .MODE_RINGER_STREAMS_AFFECTED ,
654- ((1 << AudioSystem .STREAM_RING )|(1 << AudioSystem .STREAM_NOTIFICATION )|
655- (1 << AudioSystem .STREAM_SYSTEM )|(1 << AudioSystem .STREAM_SYSTEM_ENFORCED )),
656- UserHandle .USER_CURRENT );
657- if (mVoiceCapable ) {
658- mRingerModeAffectedStreams &= ~(1 << AudioSystem .STREAM_MUSIC );
659- } else {
660- mRingerModeAffectedStreams |= (1 << AudioSystem .STREAM_MUSIC );
654+ // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting
655+ // are still needed while setVibrateSetting() and getVibrateSetting() are being
656+ // deprecated.
657+ mVibrateSetting = getValueForVibrateSetting (0 ,
658+ AudioManager .VIBRATE_TYPE_NOTIFICATION ,
659+ mHasVibrator ? AudioManager .VIBRATE_SETTING_ONLY_SILENT
660+ : AudioManager .VIBRATE_SETTING_OFF );
661+ mVibrateSetting = getValueForVibrateSetting (mVibrateSetting ,
662+ AudioManager .VIBRATE_TYPE_RINGER ,
663+ mHasVibrator ? AudioManager .VIBRATE_SETTING_ONLY_SILENT
664+ : AudioManager .VIBRATE_SETTING_OFF );
665+
666+ // make sure settings for ringer mode are consistent with device type: non voice capable
667+ // devices (tablets) include media stream in silent mode whereas phones don't.
668+ mRingerModeAffectedStreams = Settings .System .getIntForUser (cr ,
669+ Settings .System .MODE_RINGER_STREAMS_AFFECTED ,
670+ ((1 << AudioSystem .STREAM_RING )|(1 << AudioSystem .STREAM_NOTIFICATION )|
671+ (1 << AudioSystem .STREAM_SYSTEM )|(1 << AudioSystem .STREAM_SYSTEM_ENFORCED )),
672+ UserHandle .USER_CURRENT );
673+ if (mVoiceCapable ) {
674+ mRingerModeAffectedStreams &= ~(1 << AudioSystem .STREAM_MUSIC );
675+ } else {
676+ mRingerModeAffectedStreams |= (1 << AudioSystem .STREAM_MUSIC );
677+ }
678+ synchronized (mCameraSoundForced ) {
679+ if (mCameraSoundForced ) {
680+ mRingerModeAffectedStreams &= ~(1 << AudioSystem .STREAM_SYSTEM_ENFORCED );
681+ } else {
682+ mRingerModeAffectedStreams |= (1 << AudioSystem .STREAM_SYSTEM_ENFORCED );
683+ }
684+ }
685+
686+ Settings .System .putIntForUser (cr ,
687+ Settings .System .MODE_RINGER_STREAMS_AFFECTED ,
688+ mRingerModeAffectedStreams ,
689+ UserHandle .USER_CURRENT );
661690 }
662- Settings .System .putIntForUser (cr ,
663- Settings .System .MODE_RINGER_STREAMS_AFFECTED ,
664- mRingerModeAffectedStreams ,
665- UserHandle .USER_CURRENT );
666691
667692 mMuteAffectedStreams = System .getIntForUser (cr ,
668693 System .MUTE_STREAMS_AFFECTED ,
@@ -2601,12 +2626,18 @@ public synchronized void readSettings() {
26012626 // only be stale values
26022627 // on first call to readSettings() at init time, muteCount() is always 0 so we will
26032628 // always create entries for default device
2604- if ((muteCount () == 0 ) && ( mStreamType == AudioSystem .STREAM_SYSTEM ) ||
2629+ if ((mStreamType == AudioSystem .STREAM_SYSTEM ) ||
26052630 (mStreamType == AudioSystem .STREAM_SYSTEM_ENFORCED )) {
2606- mLastAudibleIndex .put (AudioSystem .DEVICE_OUT_DEFAULT ,
2607- 10 * AudioManager .DEFAULT_STREAM_VOLUME [mStreamType ]);
2608- mIndex .put (AudioSystem .DEVICE_OUT_DEFAULT ,
2609- 10 * AudioManager .DEFAULT_STREAM_VOLUME [mStreamType ]);
2631+ int index = 10 * AudioManager .DEFAULT_STREAM_VOLUME [mStreamType ];
2632+ synchronized (mCameraSoundForced ) {
2633+ if (mCameraSoundForced ) {
2634+ index = mIndexMax ;
2635+ }
2636+ }
2637+ if (muteCount () == 0 ) {
2638+ mIndex .put (AudioSystem .DEVICE_OUT_DEFAULT , index );
2639+ }
2640+ mLastAudibleIndex .put (AudioSystem .DEVICE_OUT_DEFAULT , index );
26102641 return ;
26112642 }
26122643
@@ -2618,10 +2649,11 @@ public synchronized void readSettings() {
26182649 remainingDevices &= ~device ;
26192650
26202651 // ignore settings for fixed volume devices: volume should always be at max
2621- if ((muteCount () == 0 ) &&
2622- (mStreamVolumeAlias [mStreamType ] == AudioSystem .STREAM_MUSIC ) &&
2652+ if ((mStreamVolumeAlias [mStreamType ] == AudioSystem .STREAM_MUSIC ) &&
26232653 ((device & mFixedVolumeDevices ) != 0 )) {
2624- mIndex .put (device , mIndexMax );
2654+ if (muteCount () == 0 ) {
2655+ mIndex .put (device , mIndexMax );
2656+ }
26252657 mLastAudibleIndex .put (device , mIndexMax );
26262658 continue ;
26272659 }
@@ -2676,7 +2708,9 @@ public synchronized void readSettings() {
26762708 this ,
26772709 PERSIST_DELAY );
26782710 }
2679- mIndex .put (device , getValidIndex (10 * index ));
2711+ if (muteCount () == 0 ) {
2712+ mIndex .put (device , getValidIndex (10 * index ));
2713+ }
26802714 }
26812715 }
26822716
@@ -2716,6 +2750,11 @@ public boolean adjustIndex(int deltaIndex, int device) {
27162750 public synchronized boolean setIndex (int index , int device , boolean lastAudible ) {
27172751 int oldIndex = getIndex (device , false /* lastAudible */ );
27182752 index = getValidIndex (index );
2753+ synchronized (mCameraSoundForced ) {
2754+ if ((mStreamType == AudioSystem .STREAM_SYSTEM_ENFORCED ) && mCameraSoundForced ) {
2755+ index = mIndexMax ;
2756+ }
2757+ }
27192758 mIndex .put (device , getValidIndex (index ));
27202759
27212760 if (oldIndex != index ) {
@@ -2819,6 +2858,21 @@ public synchronized void setAllIndexes(VolumeStreamState srcStream, boolean last
28192858 }
28202859 }
28212860
2861+ public synchronized void setAllIndexesToMax () {
2862+ Set set = mIndex .entrySet ();
2863+ Iterator i = set .iterator ();
2864+ while (i .hasNext ()) {
2865+ Map .Entry entry = (Map .Entry )i .next ();
2866+ entry .setValue (mIndexMax );
2867+ }
2868+ set = mLastAudibleIndex .entrySet ();
2869+ i = set .iterator ();
2870+ while (i .hasNext ()) {
2871+ Map .Entry entry = (Map .Entry )i .next ();
2872+ entry .setValue (mIndexMax );
2873+ }
2874+ }
2875+
28222876 public synchronized void mute (IBinder cb , boolean state ) {
28232877 VolumeDeathHandler handler = getDeathHandler (cb , state );
28242878 if (handler == null ) {
@@ -2967,6 +3021,8 @@ private VolumeDeathHandler getDeathHandler(IBinder cb, boolean state) {
29673021 }
29683022
29693023 private void dump (PrintWriter pw ) {
3024+ pw .print (" Mute count: " );
3025+ pw .println (muteCount ());
29703026 pw .print (" Current: " );
29713027 Set set = mIndex .entrySet ();
29723028 Iterator i = set .iterator ();
@@ -3215,6 +3271,8 @@ public void handleMessage(Message msg) {
32153271 // Restore forced usage for communcations and record
32163272 AudioSystem .setForceUse (AudioSystem .FOR_COMMUNICATION , mForcedUseForComm );
32173273 AudioSystem .setForceUse (AudioSystem .FOR_RECORD , mForcedUseForComm );
3274+ AudioSystem .setForceUse (AudioSystem .FOR_SYSTEM , mCameraSoundForced ?
3275+ AudioSystem .FORCE_SYSTEM_ENFORCED : AudioSystem .FORCE_NONE );
32183276
32193277 // Restore stream volumes
32203278 int numStreamTypes = AudioSystem .getNumStreamTypes ();
@@ -3372,6 +3430,13 @@ public void onChange(boolean selfChange) {
33723430 } else {
33733431 ringerModeAffectedStreams |= (1 << AudioSystem .STREAM_MUSIC );
33743432 }
3433+ synchronized (mCameraSoundForced ) {
3434+ if (mCameraSoundForced ) {
3435+ ringerModeAffectedStreams &= ~(1 << AudioSystem .STREAM_SYSTEM_ENFORCED );
3436+ } else {
3437+ ringerModeAffectedStreams |= (1 << AudioSystem .STREAM_SYSTEM_ENFORCED );
3438+ }
3439+ }
33753440 if (ringerModeAffectedStreams != mRingerModeAffectedStreams ) {
33763441 /*
33773442 * Ensure all stream types that should be affected by ringer mode
@@ -5587,6 +5652,48 @@ private void handleConfigurationChanged(Context context) {
55875652 0 ,
55885653 null ,
55895654 0 );
5655+
5656+ boolean cameraSoundForced = mContext .getResources ().getBoolean (
5657+ com .android .internal .R .bool .config_camera_sound_forced );
5658+ synchronized (mSettingsLock ) {
5659+ synchronized (mCameraSoundForced ) {
5660+ if (cameraSoundForced != mCameraSoundForced ) {
5661+ mCameraSoundForced = cameraSoundForced ;
5662+
5663+ VolumeStreamState s = mStreamStates [AudioSystem .STREAM_SYSTEM_ENFORCED ];
5664+ if (cameraSoundForced ) {
5665+ s .setAllIndexesToMax ();
5666+ mRingerModeAffectedStreams &=
5667+ ~(1 << AudioSystem .STREAM_SYSTEM_ENFORCED );
5668+ } else {
5669+ s .setAllIndexes (mStreamStates [AudioSystem .STREAM_SYSTEM ],
5670+ false /*lastAudible*/ );
5671+ s .setAllIndexes (mStreamStates [AudioSystem .STREAM_SYSTEM ],
5672+ true /*lastAudible*/ );
5673+ mRingerModeAffectedStreams |=
5674+ (1 << AudioSystem .STREAM_SYSTEM_ENFORCED );
5675+ }
5676+ // take new state into account for streams muted by ringer mode
5677+ setRingerModeInt (getRingerMode (), false );
5678+
5679+ sendMsg (mAudioHandler ,
5680+ MSG_SET_FORCE_USE ,
5681+ SENDMSG_QUEUE ,
5682+ AudioSystem .FOR_SYSTEM ,
5683+ cameraSoundForced ?
5684+ AudioSystem .FORCE_SYSTEM_ENFORCED : AudioSystem .FORCE_NONE ,
5685+ null ,
5686+ 0 );
5687+
5688+ sendMsg (mAudioHandler ,
5689+ MSG_SET_ALL_VOLUMES ,
5690+ SENDMSG_QUEUE ,
5691+ 0 ,
5692+ 0 ,
5693+ mStreamStates [AudioSystem .STREAM_SYSTEM_ENFORCED ], 0 );
5694+ }
5695+ }
5696+ }
55905697 } catch (Exception e ) {
55915698 Log .e (TAG , "Error retrieving device orientation: " + e );
55925699 }
@@ -5762,6 +5869,38 @@ public void disableSafeMediaVolume() {
57625869 }
57635870
57645871
5872+ //==========================================================================================
5873+ // Camera shutter sound policy.
5874+ // config_camera_sound_forced configuration option in config.xml defines if the camera shutter
5875+ // sound is forced (sound even if the device is in silent mode) or not. This option is false by
5876+ // default and can be overridden by country specific overlay in values-mccXXX/config.xml.
5877+ //==========================================================================================
5878+
5879+ // cached value of com.android.internal.R.bool.config_camera_sound_forced
5880+ private Boolean mCameraSoundForced ;
5881+
5882+ // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound
5883+ public boolean isCameraSoundForced () {
5884+ synchronized (mCameraSoundForced ) {
5885+ return mCameraSoundForced ;
5886+ }
5887+ }
5888+
5889+ private static final String [] RINGER_MODE_NAMES = new String [] {
5890+ "SILENT" ,
5891+ "VIBRATE" ,
5892+ "NORMAL"
5893+ };
5894+
5895+ private void dumpRingerMode (PrintWriter pw ) {
5896+ pw .println ("\n Ringer mode: " );
5897+ pw .println ("- mode: " +RINGER_MODE_NAMES [mRingerMode ]);
5898+ pw .print ("- ringer mode affected streams = 0x" );
5899+ pw .println (Integer .toHexString (mRingerModeAffectedStreams ));
5900+ pw .print ("- ringer mode muted streams = 0x" );
5901+ pw .println (Integer .toHexString (mRingerModeMutedStreams ));
5902+ }
5903+
57655904 @ Override
57665905 protected void dump (FileDescriptor fd , PrintWriter pw , String [] args ) {
57675906 mContext .enforceCallingOrSelfPermission (android .Manifest .permission .DUMP , TAG );
@@ -5770,6 +5909,7 @@ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
57705909 dumpRCStack (pw );
57715910 dumpRCCStack (pw );
57725911 dumpStreamStates (pw );
5912+ dumpRingerMode (pw );
57735913 pw .println ("\n Audio routes:" );
57745914 pw .print (" mMainType=0x" ); pw .println (Integer .toHexString (mCurAudioRoutes .mMainType ));
57755915 pw .print (" mBluetoothName=" ); pw .println (mCurAudioRoutes .mBluetoothName );
0 commit comments