• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 package com.android.car;
17 
18 import android.car.media.CarAudioManager;
19 import android.content.Context;
20 import android.content.res.Resources;
21 import android.media.AudioAttributes;
22 import android.util.Log;
23 
24 import java.io.PrintWriter;
25 import java.util.Arrays;
26 
27 /**
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  */
31 public class AudioRoutingPolicy {
32 
33     private final int USAGE_TYPE_INVALID = -1;
34 
35     private static final String ROUTING_POLICY_FOR_MOCKED_TEST =
36             "0:call,media,radio,unknown#1:nav_guidance,voice_command,alarm,notification,system,safety";
37 
38     /** Physical stream to logical streams mapping */
39     private final int[][] mLogicalStreams;
40     /** Logical stream to physical stream mapping */
41     private final int[] mPhysicalStreamForLogicalStream;
42 
create(Context context, int policyNumber)43     public static AudioRoutingPolicy create(Context context, int policyNumber) {
44         final Resources res = context.getResources();
45         String[] policies = res.getStringArray(R.array.audioRoutingPolicy);
46         String policy;
47         if (policyNumber > (policies.length - 1)) {
48             Log.e(CarLog.TAG_AUDIO, "AudioRoutingPolicy.create got wrong policy number:" +
49                     policyNumber + ", num of avaiable policies:" + policies.length);
50             policy = policies[0];
51         } else if (policyNumber < 0) { // this is special case for mocked testing.
52             policy = ROUTING_POLICY_FOR_MOCKED_TEST;
53         } else {
54             policy = policies[policyNumber];
55         }
56         return new AudioRoutingPolicy(policy);
57     }
58 
getStreamType(String str)59     private static int getStreamType(String str) {
60         switch (str) {
61             case "call":
62                 return CarAudioManager.CAR_AUDIO_USAGE_VOICE_CALL;
63             case "media":
64                 return CarAudioManager.CAR_AUDIO_USAGE_MUSIC;
65             case "radio":
66                 return CarAudioManager.CAR_AUDIO_USAGE_RADIO;
67             case "nav_guidance":
68                 return CarAudioManager.CAR_AUDIO_USAGE_NAVIGATION_GUIDANCE;
69             case "voice_command":
70                 return CarAudioManager.CAR_AUDIO_USAGE_VOICE_COMMAND;
71             case "alarm":
72                 return CarAudioManager.CAR_AUDIO_USAGE_ALARM;
73             case "notification":
74                 return CarAudioManager.CAR_AUDIO_USAGE_NOTIFICATION;
75             case "system":
76                 return CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SOUND;
77             case "safety":
78                 return CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SAFETY_ALERT;
79             case "unknown":
80                 return CarAudioManager.CAR_AUDIO_USAGE_DEFAULT;
81         }
82         throw new IllegalArgumentException("Wrong audioRoutingPolicy config, unknown stream type:" +
83                 str);
84     }
85 
AudioRoutingPolicy(String policy)86     private AudioRoutingPolicy(String policy) {
87         String[] streamPolicies = policy.split("#");
88         final int nPhysicalStreams = streamPolicies.length;
89         mLogicalStreams = new int[nPhysicalStreams][];
90         mPhysicalStreamForLogicalStream = new int[CarAudioManager.CAR_AUDIO_USAGE_MAX + 1];
91         for (int i = 0; i < mPhysicalStreamForLogicalStream.length; i++) {
92             mPhysicalStreamForLogicalStream[i] = USAGE_TYPE_INVALID;
93         }
94         int defaultStreamType = USAGE_TYPE_INVALID;
95         for (String streamPolicy : streamPolicies) {
96             String[] numberVsStreams = streamPolicy.split(":");
97             int physicalStream = Integer.parseInt(numberVsStreams[0]);
98             String[] logicalStreams = numberVsStreams[1].split(",");
99             int[] logicalStreamsInt = new int[logicalStreams.length];
100             for (int i = 0; i < logicalStreams.length; i++) {
101                 int logicalStreamNumber = getStreamType(logicalStreams[i]);
102                 if (logicalStreamNumber == CarAudioManager.CAR_AUDIO_USAGE_DEFAULT) {
103                     defaultStreamType = physicalStream;
104                 }
105                 logicalStreamsInt[i] = logicalStreamNumber;
106                 mPhysicalStreamForLogicalStream[logicalStreamNumber] = physicalStream;
107             }
108             Arrays.sort(logicalStreamsInt);
109             mLogicalStreams[physicalStream] = logicalStreamsInt;
110         }
111         if (defaultStreamType == USAGE_TYPE_INVALID) {
112             Log.e(CarLog.TAG_AUDIO, "Audio routing policy did not include unknown");
113             defaultStreamType = 0;
114         }
115         for (int i = 0; i < mPhysicalStreamForLogicalStream.length; i++) {
116             if (mPhysicalStreamForLogicalStream[i] == USAGE_TYPE_INVALID) {
117                 Log.w(CarLog.TAG_AUDIO, "Audio routing policy did not cover logical stream " + i);
118                 mPhysicalStreamForLogicalStream[i] = defaultStreamType;
119             }
120         }
121     }
122 
getPhysicalStreamsCount()123     public int getPhysicalStreamsCount() {
124         return mLogicalStreams.length;
125     }
126 
getLogicalStreamsForPhysicalStream(int physicalStreamNumber)127     public int[] getLogicalStreamsForPhysicalStream(int physicalStreamNumber) {
128         return mLogicalStreams[physicalStreamNumber];
129     }
130 
getPhysicalStreamForLogicalStream(int logicalStream)131     public int getPhysicalStreamForLogicalStream(int logicalStream) {
132         return mPhysicalStreamForLogicalStream[logicalStream];
133     }
134 
dump(PrintWriter writer)135     public void dump(PrintWriter writer) {
136         writer.println("*AudioRoutingPolicy*");
137         writer.println("**Logical Streams**");
138         for (int i = 0; i < mLogicalStreams.length; i++) {
139             writer.print("physical stream " + i + ":");
140             for (int logicalStream : mLogicalStreams[i]) {
141                 writer.print(Integer.toString(logicalStream) + ",");
142             }
143             writer.println("");
144         }
145     }
146 }
147