1 /*
2 * Copyright (C) 2019 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 #include <media/AudioDeviceTypeAddr.h>
18 #include <arpa/inet.h>
19 #include <iostream>
20 #include <regex>
21 #include <set>
22 #include <sstream>
23
24 #include <media/AidlConversion.h>
25
26 namespace android {
27
28 using media::audio::common::AudioDevice;
29 using media::audio::common::AudioDeviceAddress;
30
31 namespace {
32
33 static const std::string SUPPRESSED = "SUPPRESSED";
34 static const std::regex MAC_ADDRESS_REGEX("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
35
isSenstiveAddress(const std::string & address)36 bool isSenstiveAddress(const std::string &address) {
37 if (std::regex_match(address, MAC_ADDRESS_REGEX)) {
38 return true;
39 }
40
41 sockaddr_storage ss4;
42 if (inet_pton(AF_INET, address.c_str(), &ss4) > 0) {
43 return true;
44 }
45
46 sockaddr_storage ss6;
47 if (inet_pton(AF_INET6, address.c_str(), &ss6) > 0) {
48 return true;
49 }
50
51 return false;
52 }
53
54 } // namespace
55
AudioDeviceTypeAddr(audio_devices_t type,const std::string & address)56 AudioDeviceTypeAddr::AudioDeviceTypeAddr(audio_devices_t type, const std::string &address) :
57 mType(type), mAddress(address) {
58 mIsAddressSensitive = isSenstiveAddress(mAddress);
59 }
60
getAddress() const61 const char* AudioDeviceTypeAddr::getAddress() const {
62 return mAddress.c_str();
63 }
64
address() const65 const std::string& AudioDeviceTypeAddr::address() const {
66 return mAddress;
67 }
68
setAddress(const std::string & address)69 void AudioDeviceTypeAddr::setAddress(const std::string& address) {
70 mAddress = address;
71 mIsAddressSensitive = isSenstiveAddress(mAddress);
72 }
73
equals(const AudioDeviceTypeAddr & other) const74 bool AudioDeviceTypeAddr::equals(const AudioDeviceTypeAddr& other) const {
75 return mType == other.mType && mAddress == other.mAddress;
76 }
77
operator <(const AudioDeviceTypeAddr & other) const78 bool AudioDeviceTypeAddr::operator<(const AudioDeviceTypeAddr& other) const {
79 if (mType < other.mType) return true;
80 if (mType > other.mType) return false;
81
82 if (mAddress < other.mAddress) return true;
83 // if (mAddress > other.mAddress) return false;
84
85 return false;
86 }
87
operator ==(const AudioDeviceTypeAddr & rhs) const88 bool AudioDeviceTypeAddr::operator==(const AudioDeviceTypeAddr &rhs) const {
89 return equals(rhs);
90 }
91
operator !=(const AudioDeviceTypeAddr & rhs) const92 bool AudioDeviceTypeAddr::operator!=(const AudioDeviceTypeAddr &rhs) const {
93 return !operator==(rhs);
94 }
95
reset()96 void AudioDeviceTypeAddr::reset() {
97 mType = AUDIO_DEVICE_NONE;
98 setAddress("");
99 }
100
toString(bool includeSensitiveInfo) const101 std::string AudioDeviceTypeAddr::toString(bool includeSensitiveInfo) const {
102 std::stringstream sstream;
103 sstream << audio_device_to_string(mType);
104 if (sstream.str().empty()) {
105 sstream << "unknown type:0x" << std::hex << mType;
106 }
107 // IP and MAC address are sensitive information. The sensitive information will be suppressed
108 // is `includeSensitiveInfo` is false.
109 sstream << ", @:"
110 << (!includeSensitiveInfo && mIsAddressSensitive ? SUPPRESSED : mAddress);
111 return sstream.str();
112 }
113
readFromParcel(const Parcel * parcel)114 status_t AudioDeviceTypeAddr::readFromParcel(const Parcel *parcel) {
115 status_t status;
116 uint32_t rawDeviceType;
117 if ((status = parcel->readUint32(&rawDeviceType)) != NO_ERROR) return status;
118 mType = static_cast<audio_devices_t>(rawDeviceType);
119 status = parcel->readUtf8FromUtf16(&mAddress);
120 return status;
121 }
122
writeToParcel(Parcel * parcel) const123 status_t AudioDeviceTypeAddr::writeToParcel(Parcel *parcel) const {
124 status_t status;
125 if ((status = parcel->writeUint32(mType)) != NO_ERROR) return status;
126 status = parcel->writeUtf8AsUtf16(mAddress);
127 return status;
128 }
129
130
getAudioDeviceTypes(const AudioDeviceTypeAddrVector & deviceTypeAddrs)131 DeviceTypeSet getAudioDeviceTypes(const AudioDeviceTypeAddrVector& deviceTypeAddrs) {
132 DeviceTypeSet deviceTypes;
133 for (const auto& deviceTypeAddr : deviceTypeAddrs) {
134 deviceTypes.insert(deviceTypeAddr.mType);
135 }
136 return deviceTypes;
137 }
138
excludeDeviceTypeAddrsFrom(const AudioDeviceTypeAddrVector & devices,const AudioDeviceTypeAddrVector & devicesToExclude)139 AudioDeviceTypeAddrVector excludeDeviceTypeAddrsFrom(
140 const AudioDeviceTypeAddrVector& devices,
141 const AudioDeviceTypeAddrVector& devicesToExclude) {
142 std::set<AudioDeviceTypeAddr> devicesToExcludeSet(
143 devicesToExclude.begin(), devicesToExclude.end());
144 AudioDeviceTypeAddrVector remainedDevices;
145 for (const auto& device : devices) {
146 if (devicesToExcludeSet.count(device) == 0) {
147 remainedDevices.push_back(device);
148 }
149 }
150 return remainedDevices;
151 }
152
joinDeviceTypeAddrs(const AudioDeviceTypeAddrVector & devices,const AudioDeviceTypeAddrVector & devicesToJoin)153 AudioDeviceTypeAddrVector joinDeviceTypeAddrs(
154 const AudioDeviceTypeAddrVector& devices,
155 const AudioDeviceTypeAddrVector& devicesToJoin) {
156 std::set<AudioDeviceTypeAddr> devicesSet(devices.begin(), devices.end());
157 std::set<AudioDeviceTypeAddr> devicesToJoinSet(devicesToJoin.begin(), devicesToJoin.end());
158 AudioDeviceTypeAddrVector joinedDevices;
159
160 std::set_union(devicesSet.begin(), devicesSet.end(),
161 devicesToJoinSet.begin(), devicesToJoinSet.end(),
162 std::back_inserter(joinedDevices));
163
164 return joinedDevices;
165 }
166
dumpAudioDeviceTypeAddrVector(const AudioDeviceTypeAddrVector & deviceTypeAddrs,bool includeSensitiveInfo)167 std::string dumpAudioDeviceTypeAddrVector(const AudioDeviceTypeAddrVector& deviceTypeAddrs,
168 bool includeSensitiveInfo) {
169 std::stringstream stream;
170 for (auto it = deviceTypeAddrs.begin(); it != deviceTypeAddrs.end(); ++it) {
171 if (it != deviceTypeAddrs.begin()) {
172 stream << " ";
173 }
174 stream << it->toString(includeSensitiveInfo);
175 }
176 return stream.str();
177 }
178
179 ConversionResult<AudioDeviceTypeAddr>
aidl2legacy_AudioDeviceTypeAddress(const AudioDevice & aidl)180 aidl2legacy_AudioDeviceTypeAddress(const AudioDevice& aidl) {
181 audio_devices_t type;
182 std::string address;
183 RETURN_IF_ERROR(aidl2legacy_AudioDevice_audio_device(aidl, &type, &address));
184 return AudioDeviceTypeAddr(type, address);
185 }
186
187 ConversionResult<AudioDevice>
legacy2aidl_AudioDeviceTypeAddress(const AudioDeviceTypeAddr & legacy)188 legacy2aidl_AudioDeviceTypeAddress(const AudioDeviceTypeAddr& legacy) {
189 return legacy2aidl_audio_device_AudioDevice(legacy.mType, legacy.getAddress());
190 }
191
192 } // namespace android
193