1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.car;
17
18import android.car.media.CarAudioManager;
19import android.media.AudioAttributes;
20import android.os.Bundle;
21
22/**
23 * Utility class to map car usage into AudioAttributes and the other way around.
24 */
25public class CarAudioAttributesUtil {
26
27    public static final int CAR_AUDIO_USAGE_CARSERVICE_BOTTOM = 100;
28    public static final int CAR_AUDIO_USAGE_CARSERVICE_CAR_PROXY = 101;
29    public static final int CAR_AUDIO_USAGE_CARSERVICE_MEDIA_MUTE = 102;
30
31    /** Bundle key for storing media type. */
32    public static final String KEY_CAR_AUDIO_TYPE = "car_audio_type";
33
34    private static final int CAR_AUDIO_TYPE_DEFAULT = 0;
35    private static final int CAR_AUDIO_TYPE_VOICE_COMMAND = 1;
36    private static final int CAR_AUDIO_TYPE_SAFETY_ALERT = 2;
37    private static final int CAR_AUDIO_TYPE_RADIO = 3;
38    private static final int CAR_AUDIO_TYPE_CARSERVICE_BOTTOM = 4;
39    private static final int CAR_AUDIO_TYPE_CARSERVICE_CAR_PROXY = 5;
40    private static final int CAR_AUDIO_TYPE_CARSERVICE_MEDIA_MUTE = 6;
41    private static final int CAR_AUDIO_TYPE_EXTERNAL_SOURCE = 7;
42
43    /** Bundle key for storing routing type which is String. */
44    public static final String KEY_EXT_ROUTING_TYPE = "ext_routing_type";
45
46    public static AudioAttributes getAudioAttributesForCarUsage(int carUsage) {
47        switch (carUsage) {
48            case CarAudioManager.CAR_AUDIO_USAGE_MUSIC:
49                return createAudioAttributes(AudioAttributes.CONTENT_TYPE_MUSIC,
50                        AudioAttributes.USAGE_MEDIA);
51            case CarAudioManager.CAR_AUDIO_USAGE_EXTERNAL_AUDIO_SOURCE: // default to radio
52            case CarAudioManager.CAR_AUDIO_USAGE_RADIO:
53                return createCustomAudioAttributes(CAR_AUDIO_TYPE_RADIO,
54                        AudioAttributes.CONTENT_TYPE_MUSIC, AudioAttributes.USAGE_MEDIA);
55            case CarAudioManager.CAR_AUDIO_USAGE_NAVIGATION_GUIDANCE:
56                return createAudioAttributes(AudioAttributes.CONTENT_TYPE_SPEECH,
57                        AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
58            case CarAudioManager.CAR_AUDIO_USAGE_VOICE_CALL:
59                return createAudioAttributes(AudioAttributes.CONTENT_TYPE_SPEECH,
60                        AudioAttributes.USAGE_VOICE_COMMUNICATION);
61            case CarAudioManager.CAR_AUDIO_USAGE_VOICE_COMMAND:
62                return createCustomAudioAttributes(CAR_AUDIO_TYPE_VOICE_COMMAND,
63                        AudioAttributes.CONTENT_TYPE_SPEECH,
64                        AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
65            case CarAudioManager.CAR_AUDIO_USAGE_ALARM:
66                return createAudioAttributes(AudioAttributes.CONTENT_TYPE_SONIFICATION,
67                        AudioAttributes.USAGE_ALARM);
68            case CarAudioManager.CAR_AUDIO_USAGE_NOTIFICATION:
69                return createAudioAttributes(AudioAttributes.CONTENT_TYPE_SONIFICATION,
70                        AudioAttributes.USAGE_NOTIFICATION);
71            case CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SOUND:
72                return createAudioAttributes(AudioAttributes.CONTENT_TYPE_SONIFICATION,
73                        AudioAttributes.USAGE_ASSISTANCE_SONIFICATION);
74            case CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SAFETY_ALERT:
75                return createCustomAudioAttributes(CAR_AUDIO_TYPE_SAFETY_ALERT,
76                        AudioAttributes.CONTENT_TYPE_SONIFICATION,
77                        AudioAttributes.USAGE_NOTIFICATION);
78            case CAR_AUDIO_USAGE_CARSERVICE_BOTTOM:
79                return createCustomAudioAttributes(CAR_AUDIO_TYPE_CARSERVICE_BOTTOM,
80                        AudioAttributes.CONTENT_TYPE_UNKNOWN,
81                        AudioAttributes.USAGE_UNKNOWN);
82            case CAR_AUDIO_USAGE_CARSERVICE_CAR_PROXY:
83                return createCustomAudioAttributes(CAR_AUDIO_TYPE_CARSERVICE_CAR_PROXY,
84                        AudioAttributes.CONTENT_TYPE_UNKNOWN,
85                        AudioAttributes.USAGE_UNKNOWN);
86            case CAR_AUDIO_USAGE_CARSERVICE_MEDIA_MUTE:
87                return createCustomAudioAttributes(CAR_AUDIO_TYPE_CARSERVICE_MEDIA_MUTE,
88                        AudioAttributes.CONTENT_TYPE_MUSIC,
89                        AudioAttributes.USAGE_UNKNOWN);
90            case CarAudioManager.CAR_AUDIO_USAGE_DEFAULT:
91            default:
92                return createAudioAttributes(AudioAttributes.CONTENT_TYPE_UNKNOWN,
93                        AudioAttributes.USAGE_UNKNOWN);
94        }
95    }
96
97    public static int getCarUsageFromAudioAttributes(AudioAttributes attr) {
98        int usage = attr.getUsage();
99        Bundle bundle = attr.getBundle();
100        int type = CAR_AUDIO_TYPE_DEFAULT;
101        if (bundle != null) {
102            type = bundle.getInt(KEY_CAR_AUDIO_TYPE, CAR_AUDIO_TYPE_DEFAULT);
103        }
104        switch (usage) {
105            case AudioAttributes.USAGE_MEDIA:
106                switch (type) {
107                    case CAR_AUDIO_TYPE_RADIO:
108                        return CarAudioManager.CAR_AUDIO_USAGE_RADIO;
109                    case CAR_AUDIO_TYPE_EXTERNAL_SOURCE:
110                        return CarAudioManager.CAR_AUDIO_USAGE_EXTERNAL_AUDIO_SOURCE;
111                    default:
112                        return CarAudioManager.CAR_AUDIO_USAGE_MUSIC;
113                }
114            case AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
115                if (type == CAR_AUDIO_TYPE_VOICE_COMMAND) {
116                    return CarAudioManager.CAR_AUDIO_USAGE_VOICE_COMMAND;
117                } else {
118                    return CarAudioManager.CAR_AUDIO_USAGE_NAVIGATION_GUIDANCE;
119                }
120            case AudioAttributes.USAGE_VOICE_COMMUNICATION:
121                return CarAudioManager.CAR_AUDIO_USAGE_VOICE_CALL;
122            case AudioAttributes.USAGE_ALARM:
123                return CarAudioManager.CAR_AUDIO_USAGE_ALARM;
124            case AudioAttributes.USAGE_NOTIFICATION:
125                if (type == CAR_AUDIO_TYPE_SAFETY_ALERT) {
126                    return CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SAFETY_ALERT;
127                } else {
128                    return CarAudioManager.CAR_AUDIO_USAGE_NOTIFICATION;
129                }
130            case AudioAttributes.USAGE_ASSISTANCE_SONIFICATION:
131                return CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SOUND;
132            case AudioAttributes.USAGE_UNKNOWN:
133            default: {
134                switch (type) {
135                    case CAR_AUDIO_TYPE_CARSERVICE_BOTTOM:
136                        return CAR_AUDIO_USAGE_CARSERVICE_BOTTOM;
137                    case CAR_AUDIO_TYPE_CARSERVICE_CAR_PROXY:
138                        return CAR_AUDIO_USAGE_CARSERVICE_CAR_PROXY;
139                    case CAR_AUDIO_TYPE_CARSERVICE_MEDIA_MUTE:
140                        return CAR_AUDIO_USAGE_CARSERVICE_MEDIA_MUTE;
141                    default:
142                        return CarAudioManager.CAR_AUDIO_USAGE_DEFAULT;
143                }
144            }
145        }
146    }
147
148    private static AudioAttributes createAudioAttributes(int contentType, int usage) {
149        AudioAttributes.Builder builder = new AudioAttributes.Builder();
150        return builder.setContentType(contentType).setUsage(usage).build();
151    }
152
153    private static AudioAttributes createCustomAudioAttributes(int carAudioType,
154            int contentType, int usage) {
155        AudioAttributes.Builder builder = new AudioAttributes.Builder();
156        Bundle bundle = new Bundle();
157        bundle.putInt(KEY_CAR_AUDIO_TYPE, carAudioType);
158        return builder.setContentType(contentType).setUsage(usage).addBundle(bundle).build();
159    }
160
161    public static AudioAttributes getCarRadioAttributes(String radioType) {
162        AudioAttributes.Builder builder = new AudioAttributes.Builder();
163        Bundle bundle = new Bundle();
164        bundle.putInt(KEY_CAR_AUDIO_TYPE, CAR_AUDIO_TYPE_RADIO);
165        bundle.putString(KEY_EXT_ROUTING_TYPE, radioType);
166        return builder.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).
167                setUsage(AudioAttributes.USAGE_MEDIA).addBundle(bundle).build();
168    }
169
170    public static AudioAttributes getCarExtSourceAttributes(String externalSourceType) {
171        AudioAttributes.Builder builder = new AudioAttributes.Builder();
172        Bundle bundle = new Bundle();
173        bundle.putInt(KEY_CAR_AUDIO_TYPE, CAR_AUDIO_TYPE_EXTERNAL_SOURCE);
174        bundle.putString(KEY_EXT_ROUTING_TYPE, externalSourceType);
175        return builder.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).
176                setUsage(AudioAttributes.USAGE_MEDIA).addBundle(bundle).build();
177    }
178
179    /**
180     * Get ext routing type from given AudioAttributes.
181     * @param attr
182     * @return {@link CarAudioManager#CAR_RADIO_TYPE_AM_FM} if ext routing info does not exist.
183     */
184    public static String getExtRouting(AudioAttributes attr) {
185        Bundle bundle = attr.getBundle();
186        String extRouting = CarAudioManager.CAR_RADIO_TYPE_AM_FM;
187        if (bundle != null) {
188            extRouting = bundle.getString(KEY_EXT_ROUTING_TYPE);
189        }
190        return extRouting;
191    }
192}
193