Android13 CarAudioManager setVolumeGroupMute流程分析

首先看CarAudioManager的setVolumeGroupMute方法:

//packages/services/Car/car-lib/src/android/car/media/CarAudioManager.java
public final class CarAudioManager implements CarManagerBase {
    private final ICarAudio mService;
    public void setVolumeGroupMute(int zoneId, int groupId, boolean mute, int flags) {
        try {
            mService.setVolumeGroupMute(zoneId, groupId, mute, flags); //调用ICarAudio的setVolumeGroupMute方法
        } catch (RemoteException e) {
            handleRemoteExceptionFromCarService(e);
        }
    }
}

调用ICarAudio的setVolumeGroupMute方法,ICarAudio是一个接口,而CarAudioService继承了ICarAudio.Stub接口:

//packages/services/Car/service/src/com/android/car/audioCarAudioService.java
public class CarAudioService extends ICarAudio.Stub implements CarServiceBase {
    private CarVolumeGroupMuting mCarVolumeGroupMuting;
    @Override
    public void setVolumeGroupMute(int zoneId, int groupId, boolean mute, int flags) {
        enforcePermission(Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME);
        requireDynamicRouting();
        requireVolumeGroupMuting();
        synchronized (mImplLock) {
            CarVolumeGroup group = getCarVolumeGroupLocked(zoneId, groupId); //获取CarVolumeGroup
            group.setMute(mute); //调用CarVolumeGroup的setMute方法
            callbackGroupMuteChanged(zoneId, groupId, flags); //调用callbackGroupMuteChanged方法
        }
        mCarVolumeGroupMuting.carMuteChanged(); //调用CarVolumeGroupMuting的carMuteChanged方法
    }
}

以上方法调用了如下方法:

调用CarVolumeGroup的setMute方法

调用callbackGroupMuteChanged方法

调用CarVolumeGroupMuting的carMuteChanged方法

下面我们分别分析:

setMute

首先是CarVolumeGroup的setMute方法:

//packages/services/Car/service/src/com/android/car/audio/CarVolumeGroup.java
final class CarVolumeGroup {
    void setMute(boolean mute) {
        synchronized (mLock) {
            setMuteLocked(mute);
        }
    }
}

调用setMuteLocked方法:

//packages/services/Car/service/src/com/android/car/audio/CarVolumeGroup.java
final class CarVolumeGroup {
    private final CarAudioSettings mSettingsManager;
    private void setMuteLocked(boolean mute) {
        mIsMuted = mute;
        if (mSettingsManager.isPersistVolumeGroupMuteEnabled(mUserId)) {
            mSettingsManager.storeVolumeGroupMuteForUser(mUserId, mZoneId, mId, mute); //调用CarAudioSettings的storeVolumeGroupMuteForUser,存储用户静音设定
        }
    }
}

callbackGroupMuteChanged

我们分析callbackGroupMuteChanged方法:

//packages/services/Car/service/src/com/android/car/audioCarAudioService.java
public class CarAudioService extends ICarAudio.Stub implements CarServiceBase {
    private final CarVolumeCallbackHandler mCarVolumeCallbackHandler;
    private void callbackGroupMuteChanged(int zoneId, int groupId, int flags) {
        mCarVolumeCallbackHandler.onGroupMuteChange(zoneId, groupId, flags); //调用CarVolumeCallbackHandler的onGroupMuteChange方法
    }
}

调用CarVolumeCallbackHandler的onGroupMuteChange方法:

//packages/services/Car/service/src/com/android/car/audio/CarVolumeCallbackHandler.java
class CarVolumeCallbackHandler {
    public void onGroupMuteChange(int zoneId, int groupId, int flags) {
        for (BinderInterfaceContainer.BinderInterface<ICarVolumeCallback> callback :
                mVolumeCallbackContainer.getInterfaces()) {
            try {
                callback.binderInterface.onGroupMuteChanged(zoneId, groupId, flags); //调用onGroupMuteChanged回调
            } catch (RemoteException e) {
                Slogf.e(CarLog.TAG_AUDIO, "Failed to callback onGroupMuteChanged", e);
            }
        }
    }
}

调用onGroupMuteChanged回调:

//packages/services/Car/car-lib/src/android/car/media/CarAudioManager.java
public final class CarAudioManager extends CarManagerBase {
    private final EventHandler mEventHandler;
    private final ICarVolumeCallback mCarVolumeCallbackImpl =
            new android.car.media.ICarVolumeCallback.Stub() {
        @Override
        public void onMasterMuteChanged(int zoneId, int flags) {
            mEventHandler.dispatchOnMasterMuteChanged(zoneId, flags); //调用EventHandler的dispatchOnMasterMuteChanged方法
        }
    };
}

调用EventHandler的dispatchOnMasterMuteChanged方法:

//packages/services/Car/car-lib/src/android/car/media/CarAudioManager.java
public final class CarAudioManager extends CarManagerBase {
    private final class EventHandler extends Handler {
        private void dispatchOnGroupMuteChanged(int zoneId, int groupId, int flags) {
            VolumeGroupChangeInfo volumeInfo = new VolumeGroupChangeInfo(zoneId, groupId, flags);
            sendMessage(obtainMessage(MSG_GROUP_MUTE_CHANGE, volumeInfo)); //发送MSG_GROUP_MUTE_CHANGE消息
        }
    }
}

发送的MSG_GROUP_MUTE_CHANGE消息会在EventHandler中处理:

//packages/services/Car/car-lib/src/android/car/media/CarAudioManager.java
public final class CarAudioManager extends CarManagerBase {
    private final class EventHandler extends Handler {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_GROUP_MUTE_CHANGE:
                    VolumeGroupChangeInfo muteInfo = (VolumeGroupChangeInfo) msg.obj;
                    handleOnGroupMuteChanged(muteInfo.mZoneId, muteInfo.mGroupId, muteInfo.mFlags);
                    break;
            }
        }
    }
}

调用handleOnGroupMuteChanged方法:

//packages/services/Car/car-lib/src/android/car/media/CarAudioManager.java
public final class CarAudioManager extends CarManagerBase {
    private void handleOnGroupMuteChanged(int zoneId, int groupId, int flags) {
        for (CarVolumeCallback callback : mCarVolumeCallbacks) {
            callback.onGroupMuteChanged(zoneId, groupId, flags); //调用CarVolumeCallback的onGroupMuteChanged方法
        }
    }
}

carMuteChanged

我们分析carMuteChanged方法:

//packages/services/Car/service/src/com/android/car/audio/CarVolumeGroupMuting.java
final class CarVolumeGroupMuting {
    private final AudioControlWrapper mAudioControlWrapper;
    public void carMuteChanged() {
        if (Slogf.isLoggable(TAG, Log.DEBUG)) {
            Slogf.d(TAG, "carMuteChanged");
        }


        List<MutingInfo> mutingInfo = generateMutingInfo();
        setLastMutingInfo(mutingInfo);
        mAudioControlWrapper.onDevicesToMuteChange(mutingInfo); //调用AudioControlWrapper的onDevicesToMuteChange方法
    }
}

AudioControlWrapper onDevicesToMuteChange

调用AudioControlWrapper的onDevicesToMuteChange方法,AudioControlWrapper是一个接口,由AudioControlWrapperAidl实现:

//packages/services/Car/service/src/com/android/car/audio/hal/AudioControlWrapperAidl.java
public final class AudioControlWrapperAidl implements AudioControlWrapper {
    private IAudioControl mAudioControl;
    @Override
    public void onDevicesToMuteChange(@NonNull List<MutingInfo> carZonesMutingInfo) {
        Objects.requireNonNull(carZonesMutingInfo, "Muting info can not be null");
        Preconditions.checkArgument(!carZonesMutingInfo.isEmpty(), "Muting info can not be empty");
        MutingInfo[] mutingInfoToHal = carZonesMutingInfo
                .toArray(new MutingInfo[carZonesMutingInfo.size()]); //取得MutingInfo
        try {
            mAudioControl.onDevicesToMuteChange(mutingInfoToHal); //调用IAudioControl 的onDevicesToMuteChange方法
        } catch (RemoteException e) {
            Slogf.e(TAG, "onDevicesToMuteChange failed", e);
        }
    }
}

调用IAudioControl的onDevicesToMuteChange方法,IAudioControl是一个Aidl接口,由AudioControl实现,因此会调用AudioControl的onDevicesToMuteChange方法:

ndk::ScopedAStatus AudioControl::onDevicesToMuteChange(
        const std::vector<MutingInfo>& in_mutingInfos) {
    LOG(INFO) << "AudioControl::onDevicesToMuteChange";
    for (const MutingInfo& mutingInfo : in_mutingInfos) {
        LOG(INFO) << "zone: " << mutingInfo.zoneId;
        LOG(INFO) << "Devices to mute:";
        for (const auto& addressToMute : mutingInfo.deviceAddressesToMute) {
            LOG(INFO) << addressToMute;
        }
        LOG(INFO) << "Devices to unmute:";
        for (const auto& addressToUnmute : mutingInfo.deviceAddressesToUnmute) {
            LOG(INFO) << addressToUnmute;
        }
    }
    return ndk::ScopedAStatus::ok();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值