1a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi/*
2a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * Copyright (C) 2014 The Android Open Source Project
3a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi *
4a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * you may not use this file except in compliance with the License.
6a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * You may obtain a copy of the License at
7a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi *
8a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi *
10a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * See the License for the specific language governing permissions and
14a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * limitations under the License.
15a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */
16a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
17a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivipackage android.media.audiopolicy;
18a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
19a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.media.AudioAttributes;
20a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.media.AudioFormat;
21a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.media.AudioManager;
22a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.media.audiopolicy.AudioMixingRule.AttributeMatchCriterion;
23a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.os.Binder;
24a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.os.IBinder;
25a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.os.Parcel;
26a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.os.Parcelable;
27a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.util.Log;
28a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
29a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport java.util.ArrayList;
301b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Triviimport java.util.Objects;
31a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
32a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi/**
33a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * @hide
34a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi * Internal storage class for AudioPolicy configuration.
35a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi */
36a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivipublic class AudioPolicyConfig implements Parcelable {
37a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
38a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    private static final String TAG = "AudioPolicyConfig";
39a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
408fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi    protected ArrayList<AudioMix> mMixes;
410212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi    protected int mDuckingPolicy = AudioPolicy.FOCUS_POLICY_DUCKING_IN_APP;
428fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi
431b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    private String mRegistrationId = null;
448fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi
458fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi    protected AudioPolicyConfig(AudioPolicyConfig conf) {
468fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi        mMixes = conf.mMixes;
478fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi    }
48a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
49a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    AudioPolicyConfig(ArrayList<AudioMix> mixes) {
50a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        mMixes = mixes;
51a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    }
52a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
53a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    /**
54a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     * Add an {@link AudioMix} to be part of the audio policy being built.
55a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     * @param mix a non-null {@link AudioMix} to be part of the audio policy.
56a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     * @return the same Builder instance.
57a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     * @throws IllegalArgumentException
58a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     */
59a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    public void addMix(AudioMix mix) throws IllegalArgumentException {
60a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        if (mix == null) {
61a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            throw new IllegalArgumentException("Illegal null AudioMix argument");
62a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        }
63a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        mMixes.add(mix);
64a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    }
65a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
66a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    @Override
671b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    public int hashCode() {
681b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi        return Objects.hash(mMixes);
691b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    }
701b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi
711b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    @Override
72a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    public int describeContents() {
73a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        return 0;
74a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    }
75a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
76a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    @Override
77a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    public void writeToParcel(Parcel dest, int flags) {
78a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        dest.writeInt(mMixes.size());
79a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        for (AudioMix mix : mMixes) {
80a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            // write mix route flags
81a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            dest.writeInt(mix.getRouteFlags());
82a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            // write mix format
83a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            dest.writeInt(mix.getFormat().getSampleRate());
84a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            dest.writeInt(mix.getFormat().getEncoding());
85a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            dest.writeInt(mix.getFormat().getChannelMask());
86a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            // write mix rules
87a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            final ArrayList<AttributeMatchCriterion> criteria = mix.getRule().getCriteria();
88a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            dest.writeInt(criteria.size());
89a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            for (AttributeMatchCriterion criterion : criteria) {
901b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi                criterion.writeToParcel(dest);
91a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            }
92a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        }
93a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    }
94a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
95a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    private AudioPolicyConfig(Parcel in) {
96a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        mMixes = new ArrayList<AudioMix>();
97a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        int nbMixes = in.readInt();
98a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        for (int i = 0 ; i < nbMixes ; i++) {
99a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            final AudioMix.Builder mixBuilder = new AudioMix.Builder();
100a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            // read mix route flags
101a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            int routeFlags = in.readInt();
102a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            mixBuilder.setRouteFlags(routeFlags);
103a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            // read mix format
104a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            int sampleRate = in.readInt();
105a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            int encoding = in.readInt();
106a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            int channelMask = in.readInt();
107a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            final AudioFormat format = new AudioFormat.Builder().setSampleRate(sampleRate)
108a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                    .setChannelMask(channelMask).setEncoding(encoding).build();
109a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            mixBuilder.setFormat(format);
110a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            // read mix rules
111a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            int nbRules = in.readInt();
112a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            AudioMixingRule.Builder ruleBuilder = new AudioMixingRule.Builder();
113a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            for (int j = 0 ; j < nbRules ; j++) {
114a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                // read the matching rules
1151b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi                ruleBuilder.addRuleFromParcel(in);
116a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            }
117a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            mixBuilder.setMixingRule(ruleBuilder.build());
118a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            mMixes.add(mixBuilder.build());
119a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        }
120a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    }
121a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
122a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    public static final Parcelable.Creator<AudioPolicyConfig> CREATOR
123a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            = new Parcelable.Creator<AudioPolicyConfig>() {
124a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        /**
125a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi         * Rebuilds an AudioPolicyConfig previously stored with writeToParcel().
126a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi         * @param p Parcel object to read the AudioPolicyConfig from
127a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi         * @return a new AudioPolicyConfig created from the data in the parcel
128a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi         */
129a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        public AudioPolicyConfig createFromParcel(Parcel p) {
130a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            return new AudioPolicyConfig(p);
131a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        }
132a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        public AudioPolicyConfig[] newArray(int size) {
133a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            return new AudioPolicyConfig[size];
134a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        }
135a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    };
136a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
1378fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi    public String toLogFriendlyString () {
138a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        String textDump = new String("android.media.audiopolicy.AudioPolicyConfig:\n");
1391b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi        textDump += mMixes.size() + " AudioMix: "+ mRegistrationId + "\n";
140a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        for(AudioMix mix : mMixes) {
141a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            // write mix route flags
142a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            textDump += "* route flags=0x" + Integer.toHexString(mix.getRouteFlags()) + "\n";
143a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            // write mix format
144a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            textDump += "  rate=" + mix.getFormat().getSampleRate() + "Hz\n";
145a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            textDump += "  encoding=" + mix.getFormat().getEncoding() + "\n";
146a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            textDump += "  channels=0x";
147a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            textDump += Integer.toHexString(mix.getFormat().getChannelMask()).toUpperCase() +"\n";
148a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            // write mix rules
149a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            final ArrayList<AttributeMatchCriterion> criteria = mix.getRule().getCriteria();
150a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            for (AttributeMatchCriterion criterion : criteria) {
151a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                switch(criterion.mRule) {
152a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                    case AudioMixingRule.RULE_EXCLUDE_ATTRIBUTE_USAGE:
153a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                        textDump += "  exclude usage ";
154a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                        textDump += criterion.mAttr.usageToString();
155a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                        break;
156a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                    case AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE:
157a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                        textDump += "  match usage ";
158a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                        textDump += criterion.mAttr.usageToString();
159a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                        break;
1601b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi                    case AudioMixingRule.RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET:
1611b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi                        textDump += "  exclude capture preset ";
1621b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi                        textDump += criterion.mAttr.getCapturePreset();
1631b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi                        break;
1641b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi                    case AudioMixingRule.RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
1651b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi                        textDump += "  match capture preset ";
1661b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi                        textDump += criterion.mAttr.getCapturePreset();
1671b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi                        break;
168a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                    default:
169a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                        textDump += "invalid rule!";
170a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                }
171a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                textDump += "\n";
172a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            }
173a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        }
174a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        return textDump;
175a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    }
1768fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi
1771b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    protected void setRegistration(String regId) {
1781b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi        final boolean currentRegNull = (mRegistrationId == null) || mRegistrationId.isEmpty();
1791b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi        final boolean newRegNull = (regId == null) || regId.isEmpty();
1801b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi        if (!currentRegNull && !newRegNull && !mRegistrationId.equals(regId)) {
1811b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi            Log.e(TAG, "Invalid registration transition from " + mRegistrationId + " to " + regId);
1821b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi            return;
1831b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi        }
1841b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi        mRegistrationId = regId == null ? "" : regId;
1858fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi        int mixIndex = 0;
1868fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi        for (AudioMix mix : mMixes) {
1871b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi            if (!mRegistrationId.isEmpty()) {
1881b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi                mix.setRegistration(mRegistrationId + "mix" + mixTypeId(mix.getMixType()) + ":"
1891b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi                        + mixIndex++);
1901b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi            } else {
1911b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi                mix.setRegistration("");
1921b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi            }
1938fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi        }
1948fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi    }
1958fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi
1961b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    private static String mixTypeId(int type) {
1971b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi        if (type == AudioMix.MIX_TYPE_PLAYERS) return "p";
1981b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi        else if (type == AudioMix.MIX_TYPE_RECORDERS) return "r";
1991b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi        else return "i";
2001b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    }
2011b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi
2021b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    protected String getRegistration() {
2031b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi        return mRegistrationId;
2041b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    }
205a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi}
206