Skip to content

Commit 14dfe4e

Browse files
Eric LaurentAndroid (Google) Code Review
authored andcommitted
Merge "enforce camera sound according to country code" into jb-mr1-dev
2 parents b312163 + dd45d01 commit 14dfe4e

File tree

6 files changed

+211
-38
lines changed

6 files changed

+211
-38
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
/*
4+
** Copyright 2012, The Android Open Source Project
5+
**
6+
** Licensed under the Apache License, Version 2.0 (the "License");
7+
** you may not use this file except in compliance with the License.
8+
** You may obtain a copy of the License at
9+
**
10+
** http://www.apache.org/licenses/LICENSE-2.0
11+
**
12+
** Unless required by applicable law or agreed to in writing, software
13+
** distributed under the License is distributed on an "AS IS" BASIS,
14+
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
** See the License for the specific language governing permissions and
16+
** limitations under the License.
17+
*/
18+
-->
19+
20+
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
21+
22+
<!-- Whether camera shutter sound is forced or not (country specific). -->
23+
<bool name="config_camera_sound_forced">true</bool>
24+
25+
</resources>

core/res/res/values/config.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,4 +981,7 @@
981981
-->
982982
<bool name="config_wifiDisplaySupportsProtectedBuffers">false</bool>
983983

984+
<!-- Whether camera shutter sound is forced or not (country specific). -->
985+
<bool name="config_camera_sound_forced">false</bool>
986+
984987
</resources>

core/res/res/values/symbols.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@
275275
<java-symbol type="bool" name="config_enableWifiDisplay" />
276276
<java-symbol type="bool" name="config_useDevInputEventForAudioJack" />
277277
<java-symbol type="bool" name="config_safe_media_volume_enabled" />
278+
<java-symbol type="bool" name="config_camera_sound_forced" />
278279

279280
<java-symbol type="integer" name="config_cursorWindowSize" />
280281
<java-symbol type="integer" name="config_longPressOnPowerBehavior" />

media/java/android/media/AudioService.java

Lines changed: 176 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -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("\nRinger 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("\nAudio routes:");
57745914
pw.print(" mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mMainType));
57755915
pw.print(" mBluetoothName="); pw.println(mCurAudioRoutes.mBluetoothName);

media/java/android/media/AudioSystem.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,15 +354,17 @@ public static String getDeviceName(int device)
354354
public static final int FORCE_DIGITAL_DOCK = 9;
355355
public static final int FORCE_NO_BT_A2DP = 10;
356356
public static final int FORCE_REMOTE_SUBMIX = 11;
357-
private static final int NUM_FORCE_CONFIG = 12;
357+
public static final int FORCE_SYSTEM_ENFORCED = 12;
358+
private static final int NUM_FORCE_CONFIG = 13;
358359
public static final int FORCE_DEFAULT = FORCE_NONE;
359360

360361
// usage for setForceUse, must match AudioSystem::force_use
361362
public static final int FOR_COMMUNICATION = 0;
362363
public static final int FOR_MEDIA = 1;
363364
public static final int FOR_RECORD = 2;
364365
public static final int FOR_DOCK = 3;
365-
private static final int NUM_FORCE_USE = 4;
366+
public static final int FOR_SYSTEM = 4;
367+
private static final int NUM_FORCE_USE = 5;
366368

367369
// usage for AudioRecord.startRecordingSync(), must match AudioSystem::sync_event_t
368370
public static final int SYNC_EVENT_NONE = 0;

media/java/android/media/IAudioService.aidl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,6 @@ interface IAudioService {
153153
int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state);
154154

155155
AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer);
156+
157+
boolean isCameraSoundForced();
156158
}

0 commit comments

Comments
 (0)