1#!/bin/bash 2 3# Copyright (C) 2020 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17# This script is used to update audio policy configuration files 18# to comply with the updated audio_policy_configuration.xsd from V7.0. 19# 20# The main difference is the separator used in lists for attributes. 21# Since the XML Schema Definition standard only allows space to be 22# used as a separator (see https://www.w3.org/TR/xmlschema11-2/#list-datatypes) 23# the previous versions used a regular expression to validate lists 24# in attribute values. E.g. the channel masks were validated using 25# the following regexp: [_A-Z][_A-Z0-9]*(,[_A-Z][_A-Z0-9]*)* 26# This has an obvious drawback of missing typos in the config file. 27# 28# The V7.0 has shifted to defining most of the frequently changed 29# types in the XSD schema only. This allows for verifying all the values 30# in lists, but in order to comply with XML Schema requirements 31# list elements must be separated by space. 32# 33# Since the APM config files typically use include directives, 34# the script must be pointed to the main APM config file and will 35# take care all the included files automatically. 36# If the included file is a shared version from 'frameworks/av', 37# instead of updating it the script checks if there is a newer 38# version with the corresponding name suffix (e.g. 39# 'a2dp_audio_policy_configuration_7_0.xml') and updates the include 40# path instead. 41 42set -euo pipefail 43 44if (echo "$@" | grep -qe -h); then 45 echo "This script will update Audio Policy Manager config file" 46 echo "to the format required by V7.0 XSD schema from a previous" 47 echo "version." 48 echo 49 echo "USAGE: $0 [APM_XML_FILE] [OLD_VERSION]" 50 echo " APM_XML_FILE specifies the path to audio_policy_configuration.xml" 51 echo " relative to Android repository root" 52 echo " OLD_VERSION specifies the version of schema currently used" 53 echo 54 echo "Example: $0 device/generic/goldfish/audio/policy/audio_policy_configuration.xml 6.0" 55 exit 56fi 57readonly HAL_DIRECTORY=hardware/interfaces/audio 58readonly SHARED_CONFIGS_DIRECTORY=frameworks/av/services/audiopolicy/config 59readonly OLD_VERSION=${2:-$(ls ${ANDROID_BUILD_TOP}/${HAL_DIRECTORY} | grep -E '[0-9]+\.[0-9]+' | 60 sort -n | tail -n1)} 61readonly NEW_VERSION=7.0 62readonly NEW_VERSION_UNDERSCORE=7_0 63 64readonly SOURCE_CONFIG=${ANDROID_BUILD_TOP}/$1 65 66# First, validate the input using the schema of the current version 67 68echo Validating the source against the $OLD_VERSION schema 69xmllint --noout --xinclude \ 70 --nofixup-base-uris --path "$ANDROID_BUILD_TOP/$SHARED_CONFIGS_DIRECTORY" \ 71 --schema ${ANDROID_BUILD_TOP}/${HAL_DIRECTORY}/${OLD_VERSION}/config/audio_policy_configuration.xsd \ 72 ${SOURCE_CONFIG} 73if [ $? -ne 0 ]; then 74 echo 75 echo "Config file fails validation for the specified version $OLD_VERSION--unsafe to update" 76 exit 1 77fi 78 79# Find all the source files recursively 80 81SOURCE_FILES=${SOURCE_CONFIG} 82SHARED_FILES= 83findIncludes() { 84 local FILES_TO_CHECK= 85 for F in $1; do 86 local FOUND_INCLUDES=$(grep -Po '<xi:include href="\K[^"]+(?="\/>)' ${F}) 87 for I in ${FOUND_INCLUDES}; do 88 SOURCE_FULL_PATH=$(dirname ${F})/${I} 89 SHARED_FULL_PATH=${ANDROID_BUILD_TOP}/${SHARED_CONFIGS_DIRECTORY}/${I} 90 if [ -f "$SOURCE_FULL_PATH" ]; then 91 # Device-specific file. 92 SOURCE_FILES+=$'\n'${SOURCE_FULL_PATH} 93 FILES_TO_CHECK+=$'\n'${SOURCE_FULL_PATH} 94 elif [ -f "$SHARED_FULL_PATH" ]; then 95 # Shared file from the frameworks repo. 96 SHARED_FILES+=$'\n'${I} 97 FILES_TO_CHECK+=$'\n'${SHARED_FULL_PATH} 98 else 99 echo 100 echo "Include file not found: $I" 101 exit 1 102 fi 103 done 104 done 105 if [ "$FILES_TO_CHECK" ]; then 106 findIncludes "$FILES_TO_CHECK" 107 fi 108} 109findIncludes ${SOURCE_FILES} 110 111echo "Will update $1 and included device-specific files in place." 112echo "Will update paths to shared included files." 113echo "Press Ctrl-C to cancel, Enter to continue" 114read 115 116# Update 'audioPolicyConfiguration version="1.0"' -> 7.0 in the main file 117sed -i -r -e 's/(audioPolicyConfiguration version=")1.0/\17.0/' ${SOURCE_CONFIG} 118 119updateFile() { 120 FILE=$1 121 ATTR=$2 122 SEPARATOR=$3 123 SRC_LINES=$(grep -nPo "$ATTR=\"[^\"]+\"" ${FILE} || true) 124 for S in $SRC_LINES; do 125 # Prepare instruction for 'sed' for in-place editing of specified line 126 R=$(echo ${S} | sed -e 's/^[0-9]\+:/\//' | sed -e "s/$SEPARATOR/ /g") 127 S=$(echo ${S} | sed -e 's/:/s\//')${R}/ 128 echo ${S} | sed -i -f - ${FILE} 129 done 130} 131for F in $SOURCE_FILES; do 132 updateFile ${F} "channelMasks" "," 133 updateFile ${F} "samplingRates" "," 134 updateFile ${F} "flags" "|" 135done; 136 137updateIncludes() { 138 FILE=$1 139 for I in $SHARED_FILES; do 140 NEW_VERSION_I=${I%.*}_${NEW_VERSION_UNDERSCORE}.${I##*.} 141 if [ -e "$ANDROID_BUILD_TOP/$SHARED_CONFIGS_DIRECTORY/$NEW_VERSION_I" ]; then 142 echo "s/$I/$NEW_VERSION_I/g" | sed -i -f - ${FILE} 143 fi 144 done 145} 146for F in $SOURCE_FILES; do 147 updateIncludes ${F} 148done 149 150# Validate the results against the new schema 151 152echo Validating the result against the $NEW_VERSION schema 153xmllint --noout --xinclude \ 154 --nofixup-base-uris --path "$ANDROID_BUILD_TOP/$SHARED_CONFIGS_DIRECTORY" \ 155 --schema ${ANDROID_BUILD_TOP}/${HAL_DIRECTORY}/${NEW_VERSION}/config/audio_policy_configuration.xsd \ 156 ${SOURCE_CONFIG} 157if [ $? -ne 0 ]; then 158 echo 159 echo "Config file fails validation for the specified version $NEW_VERSION--please check the changes" 160 exit 1 161fi 162echo 163echo "Please check the diff and update path to APM shared files in the device makefile!" 164