blob: 0a5951976add2ccf70f0cca879aa87319d595dc4 [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);
Keun-young Park4c6834a2016-06-28 12:58:23 -070043 if (policyNumber > (policies.length - 1)) {
44 Log.e(CarLog.TAG_AUDIO, "AudioRoutingPolicy.create got wrong policy number:" +
45 policyNumber + ", num of avaiable policies:" + policies.length);
46 policyNumber = 0;
47 }
keunyoung5c7cb262015-10-19 10:47:45 -070048 return new AudioRoutingPolicy(policies[policyNumber]);
49 }
50
51 private static int getStreamType(String str) {
52 switch (str) {
53 case "call":
Keun-young Park5672e852016-02-09 19:53:48 -080054 return CarAudioManager.CAR_AUDIO_USAGE_VOICE_CALL;
keunyoung5c7cb262015-10-19 10:47:45 -070055 case "media":
Keun-young Park5672e852016-02-09 19:53:48 -080056 return CarAudioManager.CAR_AUDIO_USAGE_MUSIC;
Keun-young Park3057ebd2016-03-28 18:12:09 -070057 case "radio":
58 return CarAudioManager.CAR_AUDIO_USAGE_RADIO;
keunyoung5c7cb262015-10-19 10:47:45 -070059 case "nav_guidance":
Keun-young Park5672e852016-02-09 19:53:48 -080060 return CarAudioManager.CAR_AUDIO_USAGE_NAVIGATION_GUIDANCE;
keunyoung5c7cb262015-10-19 10:47:45 -070061 case "voice_command":
Keun-young Park5672e852016-02-09 19:53:48 -080062 return CarAudioManager.CAR_AUDIO_USAGE_VOICE_COMMAND;
keunyoung5c7cb262015-10-19 10:47:45 -070063 case "alarm":
Keun-young Park5672e852016-02-09 19:53:48 -080064 return CarAudioManager.CAR_AUDIO_USAGE_ALARM;
keunyoung5c7cb262015-10-19 10:47:45 -070065 case "notification":
Keun-young Park5672e852016-02-09 19:53:48 -080066 return CarAudioManager.CAR_AUDIO_USAGE_NOTIFICATION;
67 case "system":
68 return CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SOUND;
69 case "safety":
70 return CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SAFETY_ALERT;
keunyoung5c7cb262015-10-19 10:47:45 -070071 case "unknown":
Keun-young Park5672e852016-02-09 19:53:48 -080072 return CarAudioManager.CAR_AUDIO_USAGE_DEFAULT;
keunyoung5c7cb262015-10-19 10:47:45 -070073 }
74 throw new IllegalArgumentException("Wrong audioRoutingPolicy config, unknown stream type:" +
75 str);
76 }
77
78 private AudioRoutingPolicy(String policy) {
79 String[] streamPolicies = policy.split("#");
80 final int nPhysicalStreams = streamPolicies.length;
81 mLogicalStreams = new int[nPhysicalStreams][];
Keun-young Park5672e852016-02-09 19:53:48 -080082 mPhysicalStreamForLogicalStream = new int[CarAudioManager.CAR_AUDIO_USAGE_MAX + 1];
83 for (int i = 0; i < mPhysicalStreamForLogicalStream.length; i++) {
84 mPhysicalStreamForLogicalStream[i] = USAGE_TYPE_INVALID;
keunyounga74b9ca2015-10-21 13:33:58 -070085 }
Keun-young Park5672e852016-02-09 19:53:48 -080086 int defaultStreamType = USAGE_TYPE_INVALID;
keunyoung5c7cb262015-10-19 10:47:45 -070087 for (String streamPolicy : streamPolicies) {
88 String[] numberVsStreams = streamPolicy.split(":");
89 int physicalStream = Integer.parseInt(numberVsStreams[0]);
90 String[] logicalStreams = numberVsStreams[1].split(",");
91 int[] logicalStreamsInt = new int[logicalStreams.length];
92 for (int i = 0; i < logicalStreams.length; i++) {
93 int logicalStreamNumber = getStreamType(logicalStreams[i]);
Keun-young Park5672e852016-02-09 19:53:48 -080094 if (logicalStreamNumber == CarAudioManager.CAR_AUDIO_USAGE_DEFAULT) {
keunyounga74b9ca2015-10-21 13:33:58 -070095 defaultStreamType = physicalStream;
96 }
keunyoung5c7cb262015-10-19 10:47:45 -070097 logicalStreamsInt[i] = logicalStreamNumber;
Keun-young Park5672e852016-02-09 19:53:48 -080098 mPhysicalStreamForLogicalStream[logicalStreamNumber] = physicalStream;
keunyoung5c7cb262015-10-19 10:47:45 -070099 }
100 Arrays.sort(logicalStreamsInt);
101 mLogicalStreams[physicalStream] = logicalStreamsInt;
102 }
Keun-young Park5672e852016-02-09 19:53:48 -0800103 if (defaultStreamType == USAGE_TYPE_INVALID) {
keunyounga74b9ca2015-10-21 13:33:58 -0700104 Log.e(CarLog.TAG_AUDIO, "Audio routing policy did not include unknown");
105 defaultStreamType = 0;
106 }
Keun-young Park5672e852016-02-09 19:53:48 -0800107 for (int i = 0; i < mPhysicalStreamForLogicalStream.length; i++) {
108 if (mPhysicalStreamForLogicalStream[i] == USAGE_TYPE_INVALID) {
Keun-young Park3057ebd2016-03-28 18:12:09 -0700109 Log.w(CarLog.TAG_AUDIO, "Audio routing policy did not cover logical stream " + i);
110 mPhysicalStreamForLogicalStream[i] = defaultStreamType;
keunyounga74b9ca2015-10-21 13:33:58 -0700111 }
112 }
keunyoung5c7cb262015-10-19 10:47:45 -0700113 }
114
115 public int getPhysicalStreamsCount() {
116 return mLogicalStreams.length;
117 }
118
119 public int[] getLogicalStreamsForPhysicalStream(int physicalStreamNumber) {
120 return mLogicalStreams[physicalStreamNumber];
121 }
122
123 public int getPhysicalStreamForLogicalStream(int logicalStream) {
Keun-young Park5672e852016-02-09 19:53:48 -0800124 return mPhysicalStreamForLogicalStream[logicalStream];
keunyounga74b9ca2015-10-21 13:33:58 -0700125 }
126
keunyoung5c7cb262015-10-19 10:47:45 -0700127 public void dump(PrintWriter writer) {
128 writer.println("*AudioRoutingPolicy*");
129 writer.println("**Logical Streams**");
130 for (int i = 0; i < mLogicalStreams.length; i++) {
131 writer.print("physical stream " + i + ":");
132 for (int logicalStream : mLogicalStreams[i]) {
133 writer.print(Integer.toString(logicalStream) + ",");
134 }
135 writer.println("");
136 }
137 }
138}