Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 080bb6e3 authored by Shunkai Yao's avatar Shunkai Yao Committed by Gerrit Code Review
Browse files

Merge "AudioService: more logs and test for master mute" into main

parents 1cddcb6f 4d870624
Loading
Loading
Loading
Loading
+32 −26
Original line number Diff line number Diff line
@@ -401,6 +401,7 @@ public class AudioService extends IAudioService.Stub
    private static final int MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES = 52;
    private static final int MSG_LOWER_VOLUME_TO_RS1 = 53;
    private static final int MSG_CONFIGURATION_CHANGED = 54;
    private static final int MSG_BROADCAST_MASTER_MUTE = 55;
    /** Messages handled by the {@link SoundDoseHelper}. */
    /*package*/ static final int SAFE_MEDIA_VOLUME_MSG_START = 1000;
@@ -984,6 +985,9 @@ public class AudioService extends IAudioService.Stub
    @GuardedBy("mSettingsLock")
    private boolean mRttEnabled = false;
    private AtomicBoolean mMasterMute = new AtomicBoolean(false);
    ///////////////////////////////////////////////////////////////////////////
    // Construction
    ///////////////////////////////////////////////////////////////////////////
@@ -2748,21 +2752,18 @@ public class AudioService extends IAudioService.Stub
        }
        final int currentUser = getCurrentUserId();
        if (mUseFixedVolume) {
            AudioSystem.setMasterVolume(1.0f);
        }
        // Check the current user restriction.
        boolean masterMute =
                mUserManagerInternal.getUserRestriction(currentUser,
                        UserManager.DISALLOW_UNMUTE_DEVICE)
                        || mUserManagerInternal.getUserRestriction(currentUser,
                        UserManager.DISALLOW_ADJUST_VOLUME);
        if (mUseFixedVolume) {
            masterMute = false;
            AudioSystem.setMasterVolume(1.0f);
        }
        if (DEBUG_VOL) {
            Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser));
        }
        AudioSystem.setMasterMute(masterMute);
        broadcastMasterMuteStatus(masterMute);
        setMasterMuteInternalNoCallerCheck(
                masterMute, /* flags =*/ 0, currentUser, "readUserRestrictions");
        mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction(
                currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE);
@@ -4769,16 +4770,10 @@ public class AudioService extends IAudioService.Stub
    // UI update and Broadcast Intent
    private void sendMasterMuteUpdate(boolean muted, int flags) {
        mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags));
        broadcastMasterMuteStatus(muted);
        sendMsg(mAudioHandler, MSG_BROADCAST_MASTER_MUTE,
                SENDMSG_QUEUE, muted ? 1 : 0, 0, null, 0);
    }
    private void broadcastMasterMuteStatus(boolean muted) {
        Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION);
        intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
        sendStickyBroadcastToAll(intent);
    }
    /**
     * Sets the stream state's index, and posts a message to set system volume.
@@ -4945,18 +4940,21 @@ public class AudioService extends IAudioService.Stub
                != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        setMasterMuteInternalNoCallerCheck(mute, flags, userId);
        setMasterMuteInternalNoCallerCheck(mute, flags, userId, "setMasterMute");
    }
    private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) {
    private void setMasterMuteInternalNoCallerCheck(
            boolean mute, int flags, int userId, String eventSource) {
        if (DEBUG_VOL) {
            Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId));
            Log.d(TAG, TextUtils.formatSimple("Master mute %s, %d, user=%d from %s",
                    mute, flags, userId, eventSource));
        }
        if (!isPlatformAutomotive() && mUseFixedVolume) {
            // If using fixed volume, we don't mute.
            // TODO: remove the isPlatformAutomotive check here.
            // The isPlatformAutomotive check is added for safety but may not be necessary.
            return;
            mute = false;
        }
        // For automotive,
        // - the car service is always running as system user
@@ -4965,8 +4963,10 @@ public class AudioService extends IAudioService.Stub
        // Therefore, the getCurrentUser() is always different to the foreground user.
        if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM)
                || (getCurrentUserId() == userId)) {
            if (mute != AudioSystem.getMasterMute()) {
                AudioSystem.setMasterMute(mute);
            if (mute != mMasterMute.getAndSet(mute)) {
                sVolumeLogger.enqueue(new VolumeEvent(
                        VolumeEvent.VOL_MASTER_MUTE, mute));
                mAudioSystem.setMasterMute(mute);
                sendMasterMuteUpdate(mute, flags);
            }
        }
@@ -4974,7 +4974,7 @@ public class AudioService extends IAudioService.Stub
    /** get global mute state. */
    public boolean isMasterMute() {
        return AudioSystem.getMasterMute();
        return mMasterMute.get();
    }
    @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
@@ -9301,6 +9301,10 @@ public class AudioService extends IAudioService.Stub
                    mSystemServer.sendMicrophoneMuteChangedIntent();
                    break;
                case MSG_BROADCAST_MASTER_MUTE:
                    mSystemServer.broadcastMasterMuteStatus(msg.arg1 == 1);
                    break;
                case MSG_CHECK_MODE_FOR_UID:
                    synchronized (mDeviceBroker.mSetModeLock) {
                        if (msg.obj == null) {
@@ -9692,7 +9696,8 @@ public class AudioService extends IAudioService.Stub
                        newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
                                || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
                if (wasRestricted != isRestricted) {
                    setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId);
                    setMasterMuteInternalNoCallerCheck(
                            isRestricted, /* flags =*/ 0, userId, "onUserRestrictionsChanged");
                }
            }
        }
@@ -11122,10 +11127,11 @@ public class AudioService extends IAudioService.Stub
            pw.print("  mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled);
        }
        pw.print("  mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported);
        pw.print("  mic mute FromSwitch=" + mMicMuteFromSwitch
        pw.println("  mic mute FromSwitch=" + mMicMuteFromSwitch
                        + " FromRestrictions=" + mMicMuteFromRestrictions
                        + " FromApi=" + mMicMuteFromApi
                        + " from system=" + mMicMuteFromSystemCached);
        pw.print("  mMasterMute="); pw.println(mMasterMute.get());
        dumpAccessibilityServiceUids(pw);
        dumpAssistantServicesUids(pw);
+19 −0
Original line number Diff line number Diff line
@@ -228,6 +228,7 @@ public class AudioServiceEvents {
        static final int VOL_MUTE_STREAM_INT = 9;
        static final int VOL_SET_LE_AUDIO_VOL = 10;
        static final int VOL_ADJUST_GROUP_VOL = 11;
        static final int VOL_MASTER_MUTE = 12;

        final int mOp;
        final int mStream;
@@ -321,6 +322,17 @@ public class AudioServiceEvents {
            logMetricEvent();
        }

        /** used for VOL_MASTER_MUTE */
        VolumeEvent(int op, boolean state) {
            mOp = op;
            mStream = -1;
            mVal1 = state ? 1 : 0;
            mVal2 = 0;
            mCaller = null;
            mGroupName = null;
            logMetricEvent();
        }


        /**
         * Audio Analytics unique Id.
@@ -429,6 +441,9 @@ public class AudioServiceEvents {
                case VOL_MUTE_STREAM_INT:
                    // No value in logging metrics for this internal event
                    return;
                case VOL_MASTER_MUTE:
                    // No value in logging metrics for this internal event
                    return;
                default:
                    return;
            }
@@ -510,6 +525,10 @@ public class AudioServiceEvents {
                            .append(AudioSystem.streamToString(mStream))
                            .append(mVal1 == 1 ? ", muted)" : ", unmuted)")
                            .toString();
                case VOL_MASTER_MUTE:
                    return new StringBuilder("Master mute:")
                            .append(mVal1 == 1 ? " muted)" : " unmuted)")
                            .toString();
                default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
            }
        }
+9 −0
Original line number Diff line number Diff line
@@ -684,6 +684,15 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback,
        return AudioSystem.clearPreferredMixerAttributes(attributes, portId, uid);
    }

    /**
     * Sets master mute state in audio flinger
     * @param mute the mute state to set
     * @return operation status
     */
    public int setMasterMute(boolean mute) {
        return AudioSystem.setMasterMute(mute);
    }

    /**
     * Part of AudioService dump
     * @param pw
+14 −0
Original line number Diff line number Diff line
@@ -145,4 +145,18 @@ public class SystemServerAdapter {
            ActivityManager.broadcastStickyIntent(intent, profileId);
        }
    }

    /*package*/ void broadcastMasterMuteStatus(boolean muted) {
        Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION);
        intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                | Intent.FLAG_RECEIVER_REPLACE_PENDING
                | Intent.FLAG_RECEIVER_FOREGROUND);
        final long ident = Binder.clearCallingIdentity();
        try {
            mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }
}
+32 −8
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ package com.android.server.audio;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.after;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -42,10 +42,10 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -58,7 +58,7 @@ public class AudioServiceTest {
    public final MockitoRule mockito = MockitoJUnit.rule();

    private Context mContext;
    private AudioSystemAdapter mAudioSystem;
    private AudioSystemAdapter mSpyAudioSystem;
    private SettingsAdapter mSettingsAdapter;

    @Spy private NoOpSystemServerAdapter mSpySystemServer;
@@ -78,11 +78,11 @@ public class AudioServiceTest {
            sLooperPrepared = true;
        }
        mContext = InstrumentationRegistry.getTargetContext();
        mAudioSystem = new NoOpAudioSystemAdapter();
        mSpyAudioSystem = spy(new NoOpAudioSystemAdapter());
        mSettingsAdapter = new NoOpSettingsAdapter();
        when(mMockAppOpsManager.noteOp(anyInt(), anyInt(), anyString(), anyString(), anyString()))
                .thenReturn(AppOpsManager.MODE_ALLOWED);
        mAudioService = new AudioService(mContext, mAudioSystem, mSpySystemServer,
        mAudioService = new AudioService(mContext, mSpyAudioSystem, mSpySystemServer,
                mSettingsAdapter, mMockAudioPolicy, null, mMockAppOpsManager,
                mMockPermissionEnforcer);
    }
@@ -95,7 +95,7 @@ public class AudioServiceTest {
    public void testMuteMicrophone() throws Exception {
        Log.i(TAG, "running testMuteMicrophone");
        Assert.assertNotNull(mAudioService);
        final NoOpAudioSystemAdapter testAudioSystem = (NoOpAudioSystemAdapter) mAudioSystem;
        final NoOpAudioSystemAdapter testAudioSystem = (NoOpAudioSystemAdapter) mSpyAudioSystem;
        testAudioSystem.configureMuteMicrophoneToFail(false);
        for (boolean muted : new boolean[] { true, false}) {
            testAudioSystem.configureIsMicrophoneMuted(!muted);
@@ -120,7 +120,7 @@ public class AudioServiceTest {
    public void testMuteMicrophoneWhenFail() throws Exception {
        Log.i(TAG, "running testMuteMicrophoneWhenFail");
        Assert.assertNotNull(mAudioService);
        final NoOpAudioSystemAdapter testAudioSystem = (NoOpAudioSystemAdapter) mAudioSystem;
        final NoOpAudioSystemAdapter testAudioSystem = (NoOpAudioSystemAdapter) mSpyAudioSystem;
        testAudioSystem.configureMuteMicrophoneToFail(true);
        for (boolean muted : new boolean[] { true, false}) {
            testAudioSystem.configureIsMicrophoneMuted(!muted);
@@ -175,4 +175,28 @@ public class AudioServiceTest {
        Assert.assertEquals(false, mAudioService.isHotwordStreamSupported(false));
        Assert.assertEquals(false, mAudioService.isHotwordStreamSupported(true));
    }

    /**
     * Test master mute setter and getter
     */
    @Test
    public void testMasterMute() throws Exception {
        Log.i(TAG, "running testMasterMute");
        Assert.assertNotNull(mAudioService);
        for (boolean mute : new boolean[] { true, false}) {
            boolean wasMute = mAudioService.isMasterMute();
            mAudioService.setMasterMute(mute, 0 /* flags */, mContext.getOpPackageName(),
                    UserHandle.getCallingUserId(), null);

            Assert.assertEquals("master mute reporting wrong value",
                    mute, mAudioService.isMasterMute());

            verify(mSpyAudioSystem, times(wasMute == mute ? 0 : 1)).setMasterMute(mute);
            // verify the intent for master mute changed is supposed to be fired
            verify(mSpySystemServer,
                    after(MAX_MESSAGE_HANDLING_DELAY_MS).times(wasMute == mute ? 0 : 1))
                    .broadcastMasterMuteStatus(mute);
            reset(mSpySystemServer);
        }
    }
}
Loading