1 /*
2  * Copyright (C) 2018 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 #define LOG_TAG "AudioProductStrategy"
18 //#define LOG_NDEBUG 0
19 #include <utils/Log.h>
20 #include <media/AudioProductStrategy.h>
21 #include <media/AudioAttributes.h>
22 #include <media/AudioSystem.h>
23 
24 namespace android {
25 
readFromParcel(const Parcel * parcel)26 status_t AudioProductStrategy::readFromParcel(const Parcel *parcel)
27 {
28     mId = static_cast<product_strategy_t>(parcel->readInt32());
29     status_t ret = parcel->readUtf8FromUtf16(&mName);
30     if (ret != NO_ERROR) {
31         return ret;
32     }
33     size_t size = static_cast<size_t>(parcel->readInt32());
34     for (size_t i = 0; i < size; i++) {
35         AudioAttributes attribute;
36         ret = attribute.readFromParcel(parcel);
37         if (ret != NO_ERROR) {
38             mAudioAttributes.clear();
39             return ret;
40         }
41         mAudioAttributes.push_back(attribute);
42     }
43     return NO_ERROR;
44 }
45 
writeToParcel(Parcel * parcel) const46 status_t AudioProductStrategy::writeToParcel(Parcel *parcel) const
47 {
48     parcel->writeInt32(static_cast<int32_t>(mId));
49     parcel->writeUtf8AsUtf16(mName);
50     size_t size = mAudioAttributes.size();
51     size_t sizePosition = parcel->dataPosition();
52     parcel->writeInt32(size);
53     size_t finalSize = size;
54 
55     for (size_t i = 0; i < size; i++) {
56         size_t position = parcel->dataPosition();
57         AudioAttributes attribute(mAudioAttributes[i]);
58         status_t ret = attribute.writeToParcel(parcel);
59         if (ret != NO_ERROR) {
60             parcel->setDataPosition(position);
61             finalSize--;
62         }
63     }
64     if (size != finalSize) {
65         size_t position = parcel->dataPosition();
66         parcel->setDataPosition(sizePosition);
67         parcel->writeInt32(finalSize);
68         parcel->setDataPosition(position);
69     }
70     return NO_ERROR;
71 }
72 
attributesMatches(const audio_attributes_t refAttributes,const audio_attributes_t clientAttritubes)73 bool AudioProductStrategy::attributesMatches(const audio_attributes_t refAttributes,
74                                         const audio_attributes_t clientAttritubes)
75 {
76     if (refAttributes == AUDIO_ATTRIBUTES_INITIALIZER) {
77         // The default product strategy is the strategy that holds default attributes by convention.
78         // All attributes that fail to match will follow the default strategy for routing.
79         // Choosing the default must be done as a fallback, the attributes match shall not
80         // select the default.
81         return false;
82     }
83     return ((refAttributes.usage == AUDIO_USAGE_UNKNOWN) ||
84             (clientAttritubes.usage == refAttributes.usage)) &&
85             ((refAttributes.content_type == AUDIO_CONTENT_TYPE_UNKNOWN) ||
86              (clientAttritubes.content_type == refAttributes.content_type)) &&
87             ((refAttributes.flags == AUDIO_FLAG_NONE) ||
88              (clientAttritubes.flags != AUDIO_FLAG_NONE &&
89             (clientAttritubes.flags & refAttributes.flags) == refAttributes.flags)) &&
90             ((strlen(refAttributes.tags) == 0) ||
91              (std::strcmp(clientAttritubes.tags, refAttributes.tags) == 0));
92 }
93 
94 } // namespace android
95