Merge changes If9068025,I728e5bf9,I9d41169d

* changes:
  InputManagerService: Add Mic Mute switch support
  AudioService: Add reporting of Mic Mute on start
  InputManager: Add isMicMuted() helper
This commit is contained in:
Treehugger Robot
2019-10-02 20:20:50 +00:00
committed by Gerrit Code Review
6 changed files with 107 additions and 8 deletions

View File

@@ -76,6 +76,9 @@ interface IInputManager {
// Registers a tablet mode change listener // Registers a tablet mode change listener
void registerTabletModeChangedListener(ITabletModeChangedListener listener); void registerTabletModeChangedListener(ITabletModeChangedListener listener);
// Queries whether the device's microphone is muted by switch
int isMicMuted();
// Input device vibrator control. // Input device vibrator control.
void vibrate(int deviceId, in long[] pattern, int repeat, IBinder token); void vibrate(int deviceId, in long[] pattern, int repeat, IBinder token);
void cancelVibrate(int deviceId, IBinder token); void cancelVibrate(int deviceId, IBinder token);

View File

@@ -519,6 +519,22 @@ public final class InputManager {
return -1; return -1;
} }
/**
* Queries whether the device's microphone is muted
*
* @return The mic mute switch state which is one of {@link #SWITCH_STATE_UNKNOWN},
* {@link #SWITCH_STATE_OFF} or {@link #SWITCH_STATE_ON}.
* @hide
*/
@SwitchState
public int isMicMuted() {
try {
return mIm.isMicMuted();
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
/** /**
* Gets information about all supported keyboard layouts. * Gets information about all supported keyboard layouts.
* <p> * <p>

View File

@@ -1856,13 +1856,38 @@ public class AudioManager {
} }
} }
/**
* @hide
* Sets the microphone from switch mute on or off.
* <p>
* This method should only be used by InputManager to notify
* Audio Subsystem about Microphone Mute switch state.
*
* @param on set <var>true</var> to mute the microphone;
* <var>false</var> to turn mute off
*/
@UnsupportedAppUsage
public void setMicrophoneMuteFromSwitch(boolean on) {
final IAudioService service = getService();
try {
service.setMicrophoneMuteFromSwitch(on);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** /**
* Checks whether the microphone mute is on or off. * Checks whether the microphone mute is on or off.
* *
* @return true if microphone is muted, false if it's not * @return true if microphone is muted, false if it's not
*/ */
public boolean isMicrophoneMute() { public boolean isMicrophoneMute() {
return AudioSystem.isMicrophoneMuted(); final IAudioService service = getService();
try {
return service.isMicrophoneMuted();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} }
/** /**

View File

@@ -106,8 +106,12 @@ interface IAudioService {
List<AudioProductStrategy> getAudioProductStrategies(); List<AudioProductStrategy> getAudioProductStrategies();
boolean isMicrophoneMuted();
void setMicrophoneMute(boolean on, String callingPackage, int userId); void setMicrophoneMute(boolean on, String callingPackage, int userId);
oneway void setMicrophoneMuteFromSwitch(boolean on);
void setRingerModeExternal(int ringerMode, String caller); void setRingerModeExternal(int ringerMode, String caller);
void setRingerModeInternal(int ringerMode, String caller); void setRingerModeInternal(int ringerMode, String caller);

View File

@@ -59,6 +59,7 @@ import android.hardware.hdmi.HdmiAudioSystemClient;
import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiPlaybackClient; import android.hardware.hdmi.HdmiPlaybackClient;
import android.hardware.hdmi.HdmiTvClient; import android.hardware.hdmi.HdmiTvClient;
import android.hardware.input.InputManager;
import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager;
import android.media.AudioAttributes; import android.media.AudioAttributes;
import android.media.AudioFocusInfo; import android.media.AudioFocusInfo;
@@ -545,6 +546,10 @@ public class AudioService extends IAudioService.Stub
private String mEnabledSurroundFormats; private String mEnabledSurroundFormats;
private boolean mSurroundModeChanged; private boolean mSurroundModeChanged;
private boolean mMicMuteFromSwitch;
private boolean mMicMuteFromApi;
private boolean mMicMuteFromRestrictions;
@GuardedBy("mSettingsLock") @GuardedBy("mSettingsLock")
private int mAssistantUid; private int mAssistantUid;
@@ -882,6 +887,8 @@ public class AudioService extends IAudioService.Stub
mRoleObserver.register(); mRoleObserver.register();
onIndicateSystemReady(); onIndicateSystemReady();
setMicMuteFromSwitchInput();
} }
RoleObserver mRoleObserver; RoleObserver mRoleObserver;
@@ -1021,6 +1028,8 @@ public class AudioService extends IAudioService.Stub
sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
SENDMSG_QUEUE, 1, 0, null, 0); SENDMSG_QUEUE, 1, 0, null, 0);
setMicMuteFromSwitchInput();
} }
private void onDispatchAudioServerStateChange(boolean state) { private void onDispatchAudioServerStateChange(boolean state) {
@@ -2837,20 +2846,45 @@ public class AudioService extends IAudioService.Stub
!= PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) {
return; return;
} }
setMicrophoneMuteNoCallerCheck(on, userId); mMicMuteFromApi = on;
setMicrophoneMuteNoCallerCheck(userId);
} }
private void setMicrophoneMuteNoCallerCheck(boolean on, int userId) { /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */
public void setMicrophoneMuteFromSwitch(boolean on) {
int userId = Binder.getCallingUid();
if (userId != android.os.Process.SYSTEM_UID) {
Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!");
return;
}
mMicMuteFromSwitch = on;
setMicrophoneMuteNoCallerCheck(userId);
}
private void setMicMuteFromSwitchInput() {
InputManager im = mContext.getSystemService(InputManager.class);
final int isMicMuted = im.isMicMuted();
if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) {
setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF);
}
}
public boolean isMicrophoneMuted() {
return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi;
}
private void setMicrophoneMuteNoCallerCheck(int userId) {
final boolean muted = isMicrophoneMuted();
if (DEBUG_VOL) { if (DEBUG_VOL) {
Log.d(TAG, String.format("Mic mute %s, user=%d", on, userId)); Log.d(TAG, String.format("Mic mute %d, user=%d", muted, userId));
} }
// only mute for the current user // only mute for the current user
if (getCurrentUserId() == userId) { if (getCurrentUserId() == userId || userId == android.os.Process.SYSTEM_UID) {
final boolean currentMute = AudioSystem.isMicrophoneMuted(); final boolean currentMute = AudioSystem.isMicrophoneMuted();
final long identity = Binder.clearCallingIdentity(); final long identity = Binder.clearCallingIdentity();
AudioSystem.muteMicrophone(on); AudioSystem.muteMicrophone(muted);
Binder.restoreCallingIdentity(identity); Binder.restoreCallingIdentity(identity);
if (on != currentMute) { if (muted != currentMute) {
mContext.sendBroadcastAsUser( mContext.sendBroadcastAsUser(
new Intent(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED) new Intent(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED)
.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL); .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL);
@@ -5378,7 +5412,8 @@ public class AudioService extends IAudioService.Stub
final boolean isRestricted = final boolean isRestricted =
newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
if (wasRestricted != isRestricted) { if (wasRestricted != isRestricted) {
setMicrophoneMuteNoCallerCheck(isRestricted, userId); mMicMuteFromRestrictions = isRestricted;
setMicrophoneMuteNoCallerCheck(userId);
} }
} }

View File

@@ -47,6 +47,7 @@ import android.hardware.input.InputManager;
import android.hardware.input.InputManagerInternal; import android.hardware.input.InputManagerInternal;
import android.hardware.input.KeyboardLayout; import android.hardware.input.KeyboardLayout;
import android.hardware.input.TouchCalibration; import android.hardware.input.TouchCalibration;
import android.media.AudioManager;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
@@ -294,6 +295,9 @@ public class InputManagerService extends IInputManager.Stub
/** Switch code: Camera lens cover. When set the lens is covered. */ /** Switch code: Camera lens cover. When set the lens is covered. */
public static final int SW_CAMERA_LENS_COVER = 0x09; public static final int SW_CAMERA_LENS_COVER = 0x09;
/** Switch code: Microphone. When set it is off. */
public static final int SW_MUTE_DEVICE = 0x0e;
public static final int SW_LID_BIT = 1 << SW_LID; public static final int SW_LID_BIT = 1 << SW_LID;
public static final int SW_TABLET_MODE_BIT = 1 << SW_TABLET_MODE; public static final int SW_TABLET_MODE_BIT = 1 << SW_TABLET_MODE;
public static final int SW_KEYPAD_SLIDE_BIT = 1 << SW_KEYPAD_SLIDE; public static final int SW_KEYPAD_SLIDE_BIT = 1 << SW_KEYPAD_SLIDE;
@@ -304,6 +308,7 @@ public class InputManagerService extends IInputManager.Stub
public static final int SW_JACK_BITS = public static final int SW_JACK_BITS =
SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_JACK_PHYSICAL_INSERT_BIT | SW_LINEOUT_INSERT_BIT; SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_JACK_PHYSICAL_INSERT_BIT | SW_LINEOUT_INSERT_BIT;
public static final int SW_CAMERA_LENS_COVER_BIT = 1 << SW_CAMERA_LENS_COVER; public static final int SW_CAMERA_LENS_COVER_BIT = 1 << SW_CAMERA_LENS_COVER;
public static final int SW_MUTE_DEVICE_BIT = 1 << SW_MUTE_DEVICE;
/** Whether to use the dev/input/event or uevent subsystem for the audio jack. */ /** Whether to use the dev/input/event or uevent subsystem for the audio jack. */
final boolean mUseDevInputEventForAudioJack; final boolean mUseDevInputEventForAudioJack;
@@ -969,6 +974,11 @@ public class InputManagerService extends IInputManager.Stub
return getSwitchState(-1, InputDevice.SOURCE_ANY, SW_TABLET_MODE); return getSwitchState(-1, InputDevice.SOURCE_ANY, SW_TABLET_MODE);
} }
@Override // Binder call
public int isMicMuted() {
return getSwitchState(-1, InputDevice.SOURCE_ANY, SW_MUTE_DEVICE);
}
@Override // Binder call @Override // Binder call
public void registerTabletModeChangedListener(ITabletModeChangedListener listener) { public void registerTabletModeChangedListener(ITabletModeChangedListener listener) {
if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE, if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE,
@@ -1779,6 +1789,12 @@ public class InputManagerService extends IInputManager.Stub
mHandler.obtainMessage(MSG_DELIVER_TABLET_MODE_CHANGED, mHandler.obtainMessage(MSG_DELIVER_TABLET_MODE_CHANGED,
args).sendToTarget(); args).sendToTarget();
} }
if ((switchMask & SW_MUTE_DEVICE_BIT) != 0) {
final boolean micMute = ((switchValues & SW_MUTE_DEVICE_BIT) != 0);
AudioManager audioManager = mContext.getSystemService(AudioManager.class);
audioManager.setMicrophoneMuteFromSwitch(micMute);
}
} }
// Native callback. // Native callback.