blob: fdad5aaeb98166e3223f1944e42e5632fc8e1ac2 [file] [log] [blame]
keunyoung5c7cb262015-10-19 10:47:45 -07001/*
2 * Copyright (C) 2015 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
Keun-young Parke54ac272016-02-16 19:02:18 -080018import android.car.media.CarAudioManager;
keunyoung5c7cb262015-10-19 10:47:45 -070019import android.content.Context;
20import android.content.res.Resources;
keunyounga74b9ca2015-10-21 13:33:58 -070021import android.media.AudioAttributes;
keunyoung5c7cb262015-10-19 10:47:45 -070022import android.util.Log;
23
Keun-young Parke54ac272016-02-16 19:02:18 -080024import java.io.PrintWriter;
25import java.util.Arrays;
26
keunyounga74b9ca2015-10-21 13:33:58 -070027/**
28 * Holds audio routing policy from config.xml. R.array.audioRoutingPolicy can contain
29 * multiple policies and VEHICLE_PROPERTY_AUDIO_HW_VARIANT decide which one to use.
30 */
keunyoung5c7cb262015-10-19 10:47:45 -070031public class AudioRoutingPolicy {
Keun-young Park5672e852016-02-09 19:53:48 -080032
33 private final int USAGE_TYPE_INVALID = -1;
keunyoung5c7cb262015-10-19 10:47:45 -070034
35 /** Physical stream to logical streams mapping */
36 private final int[][] mLogicalStreams;
37 /** Logical stream to physical stream mapping */
Keun-young Park5672e852016-02-09 19:53:48 -080038 private final int[] mPhysicalStreamForLogicalStream;
keunyoung5c7cb262015-10-19 10:47:45 -070039
40 public static AudioRoutingPolicy create(Context context, int policyNumber) {
41 final Resources res = context.getResources();
42 String[] policies = res.getStringArray(R.array.audioRoutingPolicy);
43 return new AudioRoutingPolicy(policies[policyNumber]);
44 }
45
46 private static int getStreamType(String str) {
47 switch (str) {
48 case "call":
Keun-young Park5672e852016-02-09 19:53:48 -080049 return CarAudioManager.CAR_AUDIO_USAGE_VOICE_CALL;
keunyoung5c7cb262015-10-19 10:47:45 -070050 case "media":
Keun-young Park5672e852016-02-09 19:53:48 -080051 return CarAudioManager.CAR_AUDIO_USAGE_MUSIC;
Keun-young Park3057ebd2016-03-28 18:12:09 -070052 case "radio":
53 return CarAudioManager.CAR_AUDIO_USAGE_RADIO;
keunyoung5c7cb262015-10-19 10:47:45 -070054 case "nav_guidance":
Keun-young Park5672e852016-02-09 19:53:48 -080055 return CarAudioManager.CAR_AUDIO_USAGE_NAVIGATION_GUIDANCE;
keunyoung5c7cb262015-10-19 10:47:45 -070056 case "voice_command":
Keun-young Park5672e852016-02-09 19:53:48 -080057 return CarAudioManager.CAR_AUDIO_USAGE_VOICE_COMMAND;
keunyoung5c7cb262015-10-19 10:47:45 -070058 case "alarm":
Keun-young Park5672e852016-02-09 19:53:48 -080059 return CarAudioManager.CAR_AUDIO_USAGE_ALARM;
keunyoung5c7cb262015-10-19 10:47:45 -070060 case "notification":
Keun-young Park5672e852016-02-09 19:53:48 -080061 return CarAudioManager.CAR_AUDIO_USAGE_NOTIFICATION;
62 case "system":
63 return CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SOUND;
64 case "safety":
65 return CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SAFETY_ALERT;
keunyoung5c7cb262015-10-19 10:47:45 -070066 case "unknown":
Keun-young Park5672e852016-02-09 19:53:48 -080067 return CarAudioManager.CAR_AUDIO_USAGE_DEFAULT;
keunyoung5c7cb262015-10-19 10:47:45 -070068 }
69 throw new IllegalArgumentException("Wrong audioRoutingPolicy config, unknown stream type:" +
70 str);
71 }
72
73 private AudioRoutingPolicy(String policy) {
74 String[] streamPolicies = policy.split("#");
75 final int nPhysicalStreams = streamPolicies.length;
76 mLogicalStreams = new int[nPhysicalStreams][];
Keun-young Park5672e852016-02-09 19:53:48 -080077 mPhysicalStreamForLogicalStream = new int[CarAudioManager.CAR_AUDIO_USAGE_MAX + 1];
78 for (int i = 0; i < mPhysicalStreamForLogicalStream.length; i++) {
79 mPhysicalStreamForLogicalStream[i] = USAGE_TYPE_INVALID;
keunyounga74b9ca2015-10-21 13:33:58 -070080 }
Keun-young Park5672e852016-02-09 19:53:48 -080081 int defaultStreamType = USAGE_TYPE_INVALID;
keunyoung5c7cb262015-10-19 10:47:45 -070082 for (String streamPolicy : streamPolicies) {
83 String[] numberVsStreams = streamPolicy.split(":");
84 int physicalStream = Integer.parseInt(numberVsStreams[0]);
85 String[] logicalStreams = numberVsStreams[1].split(",");
86 int[] logicalStreamsInt = new int[logicalStreams.length];
87 for (int i = 0; i < logicalStreams.length; i++) {
88 int logicalStreamNumber = getStreamType(logicalStreams[i]);
Keun-young Park5672e852016-02-09 19:53:48 -080089 if (logicalStreamNumber == CarAudioManager.CAR_AUDIO_USAGE_DEFAULT) {
keunyounga74b9ca2015-10-21 13:33:58 -070090 defaultStreamType = physicalStream;
91 }
keunyoung5c7cb262015-10-19 10:47:45 -070092 logicalStreamsInt[i] = logicalStreamNumber;
Keun-young Park5672e852016-02-09 19:53:48 -080093 mPhysicalStreamForLogicalStream[logicalStreamNumber] = physicalStream;
keunyoung5c7cb262015-10-19 10:47:45 -070094 }
95 Arrays.sort(logicalStreamsInt);
96 mLogicalStreams[physicalStream] = logicalStreamsInt;
97 }
Keun-young Park5672e852016-02-09 19:53:48 -080098 if (defaultStreamType == USAGE_TYPE_INVALID) {
keunyounga74b9ca2015-10-21 13:33:58 -070099 Log.e(CarLog.TAG_AUDIO, "Audio routing policy did not include unknown");
100 defaultStreamType = 0;
101 }
Keun-young Park5672e852016-02-09 19:53:48 -0800102 for (int i = 0; i < mPhysicalStreamForLogicalStream.length; i++) {
103 if (mPhysicalStreamForLogicalStream[i] == USAGE_TYPE_INVALID) {
Keun-young Park3057ebd2016-03-28 18:12:09 -0700104 Log.w(CarLog.TAG_AUDIO, "Audio routing policy did not cover logical stream " + i);
105 mPhysicalStreamForLogicalStream[i] = defaultStreamType;
keunyounga74b9ca2015-10-21 13:33:58 -0700106 }
107 }
keunyoung5c7cb262015-10-19 10:47:45 -0700108 }
109
110 public int getPhysicalStreamsCount() {
111 return mLogicalStreams.length;
112 }
113
114 public int[] getLogicalStreamsForPhysicalStream(int physicalStreamNumber) {
115 return mLogicalStreams[physicalStreamNumber];
116 }
117
118 public int getPhysicalStreamForLogicalStream(int logicalStream) {
Keun-young Park5672e852016-02-09 19:53:48 -0800119 return mPhysicalStreamForLogicalStream[logicalStream];
keunyounga74b9ca2015-10-21 13:33:58 -0700120 }
121
keunyoung5c7cb262015-10-19 10:47:45 -0700122 public void dump(PrintWriter writer) {
123 writer.println("*AudioRoutingPolicy*");
124 writer.println("**Logical Streams**");
125 for (int i = 0; i < mLogicalStreams.length; i++) {
126 writer.print("physical stream " + i + ":");
127 for (int logicalStream : mLogicalStreams[i]) {
128 writer.print(Integer.toString(logicalStream) + ",");
129 }
130 writer.println("");
131 }
132 }
133}