1 /*
2  * Copyright (C) 2021 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 
17 package com.android.car.audio;
18 
19 import static android.car.builtin.media.AudioManagerHelper.usageToXsdString;
20 import static android.media.audio.common.AudioContentType.UNKNOWN;
21 
22 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO;
23 
24 import android.annotation.NonNull;
25 import android.hardware.audio.common.PlaybackTrackMetadata;
26 import android.util.proto.ProtoOutputStream;
27 
28 import com.android.car.audio.CarAudioDumpProto.CarDuckingProto;
29 import com.android.car.audio.CarAudioDumpProto.CarDuckingProto.CarDuckingInfoProto;
30 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport;
31 import com.android.car.internal.util.IndentingPrintWriter;
32 
33 import java.util.Arrays;
34 import java.util.List;
35 import java.util.Objects;
36 
37 /**
38  * Ducking information for a given car audio zone based on its focus state.
39  */
40 public final class CarDuckingInfo {
41     public final int mZoneId;
42     public final List<String> mAddressesToDuck;
43     public final List<String> mAddressesToUnduck;
44     public final List<PlaybackTrackMetadata> mPlaybackMetaDataHoldingFocus;
45 
CarDuckingInfo( int zoneId, @NonNull List<String> addressesToDuck, @NonNull List<String> addressesToUnduck, @NonNull List<PlaybackTrackMetadata> playbackMetaDataHoldingFocus)46     public CarDuckingInfo(
47             int zoneId,
48             @NonNull List<String> addressesToDuck,
49             @NonNull List<String> addressesToUnduck,
50             @NonNull List<PlaybackTrackMetadata> playbackMetaDataHoldingFocus) {
51         mZoneId = zoneId;
52         mAddressesToDuck = Objects.requireNonNull(addressesToDuck);
53         mAddressesToUnduck = Objects.requireNonNull(addressesToUnduck);
54         mPlaybackMetaDataHoldingFocus = Objects.requireNonNull(playbackMetaDataHoldingFocus);
55     }
56 
getZoneId()57     public int getZoneId() {
58         return mZoneId;
59     }
60 
getAddressesToDuck()61     public @NonNull List<String> getAddressesToDuck() {
62         return mAddressesToDuck;
63     }
64 
getAddressesToUnduck()65     public @NonNull List<String> getAddressesToUnduck() {
66         return mAddressesToUnduck;
67     }
68 
getPlaybackMetaDataHoldingFocus()69     public @NonNull List<PlaybackTrackMetadata> getPlaybackMetaDataHoldingFocus() {
70         return mPlaybackMetaDataHoldingFocus;
71     }
72 
73     @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO)
dump(IndentingPrintWriter writer)74     void dump(IndentingPrintWriter writer) {
75         writer.printf("Ducking Info for zone %d \n", mZoneId);
76         writer.increaseIndent();
77         writer.printf("Addresses to duck: %s\n",
78                 String.join(", ", mAddressesToDuck));
79         writer.printf("Addresses to unduck: %s\n",
80                 String.join(", ", mAddressesToUnduck));
81         writer.println("Audio Attributes holding focus:");
82         writer.increaseIndent();
83         for (int index = 0; index < mPlaybackMetaDataHoldingFocus.size(); index++) {
84             PlaybackTrackMetadata playbackTrackMetaData = mPlaybackMetaDataHoldingFocus.get(index);
85             writer.printf(
86                     "usage=%s, content type=%s, tags=%s\n",
87                     usageToXsdString(playbackTrackMetaData.usage),
88                     (playbackTrackMetaData.contentType != UNKNOWN
89                             ? playbackTrackMetaData.contentType
90                             : ""),
91                     (playbackTrackMetaData.tags.length != 0
92                             ? Arrays.toString(playbackTrackMetaData.tags)
93                             : ""));
94         }
95         writer.decreaseIndent();
96         writer.println();
97         writer.decreaseIndent();
98     }
99 
100     @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO)
dumpProto(ProtoOutputStream proto)101     void dumpProto(ProtoOutputStream proto) {
102         long carDuckingInfoToken = proto.start(CarDuckingProto.CURRENT_DUCKING_INFOS);
103         proto.write(CarDuckingInfoProto.ZONE_ID, mZoneId);
104         for (int index = 0; index < mAddressesToDuck.size(); index++) {
105             proto.write(CarDuckingInfoProto.ADDRESSES_TO_DUCK, mAddressesToDuck.get(index));
106         }
107         for (int index = 0; index < mAddressesToUnduck.size(); index++) {
108             proto.write(CarDuckingInfoProto.ADDRESSES_TO_UNDUCK, mAddressesToUnduck.get(index));
109         }
110         for (int index = 0; index < mPlaybackMetaDataHoldingFocus.size(); index++) {
111             PlaybackTrackMetadata playbackTrackMetaData = mPlaybackMetaDataHoldingFocus.get(index);
112             long playbackMetaDataToken = proto.start(CarDuckingInfoProto
113                     .PLAYBACK_META_DATA_HOLDING_FOCUS);
114             proto.write(CarDuckingInfoProto.PlaybackTrackMetaData.USAGE,
115                     usageToXsdString(playbackTrackMetaData.usage));
116             if (playbackTrackMetaData.contentType != UNKNOWN) {
117                 proto.write(CarDuckingInfoProto.PlaybackTrackMetaData.CONTENT_TYPE,
118                         playbackTrackMetaData.contentType);
119             }
120             for (int tagIndex = 0; tagIndex < playbackTrackMetaData.tags.length; tagIndex++) {
121                 proto.write(CarDuckingInfoProto.PlaybackTrackMetaData.TAGS,
122                         playbackTrackMetaData.tags[tagIndex]);
123             }
124             proto.end(playbackMetaDataToken);
125         }
126         proto.end(carDuckingInfoToken);
127     }
128 }
129