1 /*
2  * Copyright (C) 2022 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 "VirtualProgram.h"
18 
19 #include <broadcastradio-utils-aidl/Utils.h>
20 #include "resources.h"
21 
22 #include <android-base/logging.h>
23 
24 namespace aidl::android::hardware::broadcastradio {
25 
26 using ::std::vector;
27 
operator ProgramInfo() const28 VirtualProgram::operator ProgramInfo() const {
29     ProgramInfo info = {};
30 
31     info.selector = selector;
32 
33     IdentifierType programType = selector.primaryId.type;
34     bool isDigital = (programType != IdentifierType::AMFM_FREQUENCY_KHZ &&
35                       programType != IdentifierType::RDS_PI);
36 
37     auto selectId = [&info](const IdentifierType& type) {
38         return utils::makeIdentifier(type, utils::getId(info.selector, type));
39     };
40 
41     switch (programType) {
42         case IdentifierType::AMFM_FREQUENCY_KHZ:
43             info.logicallyTunedTo = info.physicallyTunedTo =
44                     selectId(IdentifierType::AMFM_FREQUENCY_KHZ);
45             break;
46         case IdentifierType::RDS_PI:
47             info.logicallyTunedTo = selectId(IdentifierType::RDS_PI);
48             info.physicallyTunedTo = selectId(IdentifierType::AMFM_FREQUENCY_KHZ);
49             break;
50         case IdentifierType::HD_STATION_ID_EXT:
51             info.logicallyTunedTo = selectId(IdentifierType::HD_STATION_ID_EXT);
52             if (utils::hasId(info.selector, IdentifierType::AMFM_FREQUENCY_KHZ)) {
53                 info.physicallyTunedTo = selectId(IdentifierType::AMFM_FREQUENCY_KHZ);
54             } else {
55                 info.physicallyTunedTo = utils::makeIdentifier(
56                         IdentifierType::AMFM_FREQUENCY_KHZ, utils::getHdFrequency(info.selector));
57             }
58             break;
59         case IdentifierType::DAB_SID_EXT:
60             info.logicallyTunedTo = selectId(IdentifierType::DAB_SID_EXT);
61             info.physicallyTunedTo = selectId(IdentifierType::DAB_FREQUENCY_KHZ);
62             break;
63         case IdentifierType::DRMO_SERVICE_ID:
64             info.logicallyTunedTo = selectId(IdentifierType::DRMO_SERVICE_ID);
65             info.physicallyTunedTo = selectId(IdentifierType::DRMO_FREQUENCY_KHZ);
66             break;
67         case IdentifierType::SXM_SERVICE_ID:
68             info.logicallyTunedTo = selectId(IdentifierType::SXM_SERVICE_ID);
69             info.physicallyTunedTo = selectId(IdentifierType::SXM_CHANNEL);
70             break;
71         default:
72             LOG(FATAL) << "unsupported program type: " << toString(programType);
73             return {};
74     }
75 
76     info.infoFlags |= (ProgramInfo::FLAG_TUNABLE | ProgramInfo::FLAG_STEREO);
77     info.signalQuality = isDigital ? kSignalQualityDigital : kSignalQualityNonDigital;
78 
79     info.metadata = vector<Metadata>({
80             Metadata::make<Metadata::rdsPs>(programName),
81             Metadata::make<Metadata::songTitle>(songTitle),
82             Metadata::make<Metadata::songArtist>(songArtist),
83             Metadata::make<Metadata::stationIcon>(resources::kDemoPngId),
84             Metadata::make<Metadata::albumArt>(resources::kDemoPngId),
85     });
86 
87     info.vendorInfo = vector<VendorKeyValue>({
88             {"com.android.sample", "sample"},
89             {"com.android.sample.VirtualProgram", "VirtualProgram"},
90     });
91 
92     return info;
93 }
94 
operator <(const VirtualProgram & lhs,const VirtualProgram & rhs)95 bool operator<(const VirtualProgram& lhs, const VirtualProgram& rhs) {
96     return utils::ProgramSelectorComparator()(lhs.selector, rhs.selector);
97 }
98 
99 }  // namespace aidl::android::hardware::broadcastradio
100