10abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent/*
20abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * Copyright (C) 2014 The Android Open Source Project
30abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent *
40abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
50abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * you may not use this file except in compliance with the License.
60abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * You may obtain a copy of the License at
70abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent *
80abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
90abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent *
100abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * Unless required by applicable law or agreed to in writing, software
110abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
120abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * See the License for the specific language governing permissions and
140abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * limitations under the License.
150abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent */
160abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
170abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurentpackage android.media;
180abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
190abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent/**
200abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * An audio port is a node of the audio framework or hardware that can be connected to or
210abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * disconnect from another audio node to create a specific audio routing configuration.
220abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * Examples of audio ports are an output device (speaker) or an output mix (see AudioMixPort).
230abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * All attributes that are relevant for applications to make routing selection are decribed
240abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * in an AudioPort,  in particular:
250abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * - possible channel mask configurations.
260abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * - audio format (PCM 16bit, PCM 24bit...)
270abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * - gain: a port can be associated with one or more gain controllers (see AudioGain).
280abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent *
290abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * This object is always created by the framework and read only by applications.
300abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * A list of all audio port descriptors currently available for applications to control
310abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * is obtained by AudioManager.listAudioPorts().
320abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * An application can obtain an AudioPortConfig for a valid configuration of this port
330abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * by calling AudioPort.buildConfig() and use this configuration
340abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * to create a connection between audio sinks and sources with AudioManager.connectAudioPatch()
350abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent *
360abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent * @hide
370abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent */
380abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurentpublic class AudioPort {
3910804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    private static final String TAG = "AudioPort";
400abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
410abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
420abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * For use by the audio framework.
430abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
440abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public static final int ROLE_NONE = 0;
450abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
460abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * The audio port is a source (produces audio)
470abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
480abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public static final int ROLE_SOURCE = 1;
490abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
500abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * The audio port is a sink (consumes audio)
510abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
520abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public static final int ROLE_SINK = 2;
530abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
540abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
550abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * audio port type for use by audio framework implementation
560abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
570abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public static final int TYPE_NONE = 0;
580abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
590abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
600abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public static final int TYPE_DEVICE = 1;
610abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
620abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
630abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public static final int TYPE_SUBMIX = 2;
640abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
650abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
660abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public static final int TYPE_SESSION = 3;
670abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
680abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
690abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    AudioHandle mHandle;
7007cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood    protected final int mRole;
7110804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    private final String mName;
720abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    private final int[] mSamplingRates;
730abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    private final int[] mChannelMasks;
74f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    private final int[] mChannelIndexMasks;
750abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    private final int[] mFormats;
760abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    private final AudioGain[] mGains;
770abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    private AudioPortConfig mActiveConfig;
780abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
7910804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    AudioPort(AudioHandle handle, int role, String name,
80f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean            int[] samplingRates, int[] channelMasks, int[] channelIndexMasks,
810abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent            int[] formats, AudioGain[] gains) {
8210804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean
830abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        mHandle = handle;
840abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        mRole = role;
8510804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean        mName = name;
860abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        mSamplingRates = samplingRates;
870abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        mChannelMasks = channelMasks;
88f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean        mChannelIndexMasks = channelIndexMasks;
890abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        mFormats = formats;
900abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        mGains = gains;
910abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    }
920abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
930abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    AudioHandle handle() {
940abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        return mHandle;
950abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    }
960abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
970abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
984bcdba848449b33d7022de527c526943aff1f5fdEric Laurent     * Get the system unique device ID.
994bcdba848449b33d7022de527c526943aff1f5fdEric Laurent     */
1004bcdba848449b33d7022de527c526943aff1f5fdEric Laurent    public int id() {
1014bcdba848449b33d7022de527c526943aff1f5fdEric Laurent        return mHandle.id();
1024bcdba848449b33d7022de527c526943aff1f5fdEric Laurent    }
1034bcdba848449b33d7022de527c526943aff1f5fdEric Laurent
1044bcdba848449b33d7022de527c526943aff1f5fdEric Laurent
1054bcdba848449b33d7022de527c526943aff1f5fdEric Laurent    /**
1060abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * Get the audio port role
1070abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
1080abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public int role() {
1090abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        return mRole;
1100abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    }
1110abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
1120abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
11310804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean     * Get the human-readable name of this port. Perhaps an internal
11410804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean     * designation or an physical device.
11510804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean     */
11610804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    public String name() {
11710804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean        return mName;
11810804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    }
11910804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean
12010804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    /**
1210abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * Get the list of supported sampling rates
1220abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * Empty array if sampling rate is not relevant for this audio port
1230abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
1240abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public int[] samplingRates() {
1250abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        return mSamplingRates;
1260abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    }
1270abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
1280abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
1290abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * Get the list of supported channel mask configurations
1300abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * (e.g AudioFormat.CHANNEL_OUT_STEREO)
1310abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * Empty array if channel mask is not relevant for this audio port
1320abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
1330abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public int[] channelMasks() {
1340abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        return mChannelMasks;
1350abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    }
1360abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
1370abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
138f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean     * Get the list of supported channel index mask configurations
139f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean     * (e.g 0x0003 means 2 channel, 0x000F means 4 channel....)
140f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean     * Empty array if channel index mask is not relevant for this audio port
141f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean     */
142f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    public int[] channelIndexMasks() {
143f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean        return mChannelIndexMasks;
144f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    }
145f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean
146f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    /**
1470abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * Get the list of supported audio format configurations
1480abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * (e.g AudioFormat.ENCODING_PCM_16BIT)
1490abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * Empty array if format is not relevant for this audio port
1500abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
1510abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public int[] formats() {
1520abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        return mFormats;
1530abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    }
1540abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
1550abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
1560abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * Get the list of gain descriptors
1570abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * Empty array if this port does not have gain control
1580abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
1590abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public AudioGain[] gains() {
1600abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        return mGains;
1610abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    }
1620abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
1630abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
1640abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * Get the gain descriptor at a given index
1650abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
1660abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    AudioGain gain(int index) {
167b4e0909fc4fb08f513cb2b39a919b189621be87cEric Laurent        if (index < 0 || index >= mGains.length) {
1683a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent            return null;
1693a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        }
1700abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        return mGains[index];
1710abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    }
1720abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
1730abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
1740abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * Build a specific configuration of this audio port for use by methods
1750abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * like AudioManager.connectAudioPatch().
1760abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * @param channelMask The desired channel mask. AudioFormat.CHANNEL_OUT_DEFAULT if no change
1770abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * from active configuration requested.
1780abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * @param format The desired audio format. AudioFormat.ENCODING_DEFAULT if no change
1790abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * from active configuration requested.
1800abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * @param gain The desired gain. null if no gain changed requested.
1810abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
1820abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public AudioPortConfig buildConfig(int samplingRate, int channelMask, int format,
1830abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent                                        AudioGainConfig gain) {
1840abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        return new AudioPortConfig(this, samplingRate, channelMask, format, gain);
1850abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    }
1860abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
1870abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    /**
1880abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     * Get currently active configuration of this audio port.
1890abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent     */
1900abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public AudioPortConfig activeConfig() {
1910abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        return mActiveConfig;
1920abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    }
1930abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
1940abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    @Override
1950abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public boolean equals(Object o) {
1960abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        if (o == null || !(o instanceof AudioPort)) {
1970abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent            return false;
1980abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        }
1990abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        AudioPort ap = (AudioPort)o;
2000abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        return mHandle.equals(ap.handle());
2010abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    }
2020abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
2030abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    @Override
2040abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    public int hashCode() {
2050abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent        return mHandle.hashCode();
2060abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent    }
2070abcc5a0bbf2ad6b70b461cec150b70cfe55d239Eric Laurent
2082754fd0cd3f055b1d5f7f2ea1470b4d84011b379Mike Lockwood    @Override
2092754fd0cd3f055b1d5f7f2ea1470b4d84011b379Mike Lockwood    public String toString() {
21007cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood        String role = Integer.toString(mRole);
21107cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood        switch (mRole) {
21207cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood            case ROLE_NONE:
21307cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood                role = "NONE";
21407cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood                break;
21507cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood            case ROLE_SOURCE:
21607cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood                role = "SOURCE";
21707cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood                break;
21807cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood            case ROLE_SINK:
21907cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood                role = "SINK";
22007cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood                break;
22107cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood        }
22207cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood        return "{mHandle: " + mHandle
22307cd124b09a63985f0b200de248fab165f736ae4Mike Lockwood                + ", mRole: " + role
2242754fd0cd3f055b1d5f7f2ea1470b4d84011b379Mike Lockwood                + "}";
2252754fd0cd3f055b1d5f7f2ea1470b4d84011b379Mike Lockwood    }
2262754fd0cd3f055b1d5f7f2ea1470b4d84011b379Mike Lockwood}
227