• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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