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 
18 #include <fuzzer/FuzzedDataProvider.h>
19 
20 #include "audio_hal_interface/le_audio_software.h"
21 #include "osi/include/properties.h"
22 
23 using ::bluetooth::audio::le_audio::LeAudioClientInterface;
24 
25 constexpr int32_t kRandomStringLength = 256;
26 
27 constexpr uint8_t kBitsPerSample[] = {16, 24, 32};
28 
29 constexpr uint8_t kChannelCount[] = {1, 2};
30 
31 constexpr uint32_t kSampleRates[] = {16000, 24000, 44100, 48000, 88200, 96000};
32 
33 extern "C" {
android_get_exported_namespace(const char *)34 struct android_namespace_t* android_get_exported_namespace(const char*) { return nullptr; }
35 }
36 
onResume(bool)37 bool onResume(bool) { return true; }
38 
onSuspend(void)39 bool onSuspend(void) { return true; }
40 
onMetadataUpdate(const source_metadata_v7_t &,bluetooth::le_audio::DsaMode)41 bool onMetadataUpdate(const source_metadata_v7_t&, bluetooth::le_audio::DsaMode) { return true; }
42 
onSinkMetadataUpdate(const sink_metadata_v7_t &)43 bool onSinkMetadataUpdate(const sink_metadata_v7_t&) { return true; }
44 
source_init_delayed(void)45 static void source_init_delayed(void) {}
46 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)47 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
48   FuzzedDataProvider fdp(data, size);
49   osi_property_set("persist.bluetooth.a2dp_offload.disabled",
50                    fdp.PickValueInArray({"true", "false"}));
51   std::string name = fdp.ConsumeRandomLengthString(kRandomStringLength);
52   bluetooth::common::MessageLoopThread messageLoopThread(name);
53   messageLoopThread.StartUp();
54   messageLoopThread.DoInThread(FROM_HERE, base::BindOnce(&source_init_delayed));
55 
56   LeAudioClientInterface* interface = LeAudioClientInterface::Get();
57 
58   bluetooth::audio::le_audio::StreamCallbacks streamCb = {onResume, onSuspend, onMetadataUpdate,
59                                                           onSinkMetadataUpdate};
60 
61   if (!interface->IsSourceAcquired()) {
62     LeAudioClientInterface::Source* source = interface->GetSource(streamCb, &messageLoopThread);
63     if (source != nullptr) {
64       uint16_t delay = fdp.ConsumeIntegral<uint16_t>();
65       source->SetRemoteDelay(delay);
66       LeAudioClientInterface::PcmParameters params;
67       params.data_interval_us =
68               fdp.ConsumeIntegralInRange<uint32_t>(1000, std::numeric_limits<uint32_t>::max());
69       params.sample_rate = fdp.PickValueInArray(kSampleRates);
70       params.bits_per_sample = fdp.PickValueInArray(kBitsPerSample);
71       params.channels_count = fdp.PickValueInArray(kChannelCount);
72       source->SetPcmParameters(params);
73       source->StartSession();
74       source->StopSession();
75       source->Cleanup();
76     }
77     interface->ReleaseSource(source);
78   }
79 
80   if (!interface->IsUnicastSinkAcquired()) {
81     LeAudioClientInterface::Sink* sink = interface->GetSink(streamCb, &messageLoopThread, false);
82     if (sink != nullptr) {
83       uint16_t delay = fdp.ConsumeIntegral<uint16_t>();
84       sink->SetRemoteDelay(delay);
85       LeAudioClientInterface::PcmParameters params;
86       params.data_interval_us =
87               fdp.ConsumeIntegralInRange<uint32_t>(1000, std::numeric_limits<uint32_t>::max());
88       params.sample_rate = fdp.PickValueInArray(kSampleRates);
89       params.bits_per_sample = fdp.PickValueInArray(kBitsPerSample);
90       params.channels_count = fdp.PickValueInArray(kChannelCount);
91       sink->SetPcmParameters(params);
92       sink->StartSession();
93       sink->StopSession();
94       sink->Cleanup();
95     }
96     interface->ReleaseSink(sink);
97   }
98 
99   messageLoopThread.ShutDown();
100   return 0;
101 }
102