Skip to content

Commit ea1bf33

Browse files
committed
bring back segfault
1 parent 2b1ff85 commit ea1bf33

File tree

4 files changed

+138
-67
lines changed

4 files changed

+138
-67
lines changed

app/src/main/cpp/NativeTrack.cpp

+102-37
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <cstring>
66
#include <android/log_macros.h>
77
#include <bits/timespec.h>
8+
#include <unistd.h>
89
#include "helpers.h"
910

1011
extern void *libaudioclient_handle;
@@ -34,6 +35,9 @@ typedef void*(*ZN7android10AudioTrackC1Ev_t)(void* thisptr);
3435
static ZN7android10AudioTrackC1Ev_t ZN7android10AudioTrackC1Ev = nullptr;
3536
typedef void(*ZN7android7RefBase12weakref_type7decWeakEPKv_t)(void* thisptr, void* id);
3637
static ZN7android7RefBase12weakref_type7decWeakEPKv_t ZN7android7RefBase12weakref_type7decWeakEPKv = nullptr;
38+
typedef int32_t(*ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjm20audio_output_flags_tPFviPvS4_ES4_jRKNS_2spINS_7IMemoryEEEbiNS0_13transfer_typeEPK20audio_offload_info_tiiPK18audio_attributes_t_t)
39+
(void* thisptr, int32_t streamType, uint32_t sampleRate, uint32_t format, uint32_t channelMask, size_t frameCount /* = 0 */, uint32_t flags /* = 0 */, legacy_callback_t callback /* = nullptr */, void* user /* = nullptr */, int32_t notificationFrames /* = 0 */, fake_sp& sharedMemory /* = nullptr */, bool threadCanCallJava /* = false */, int32_t audioSessionId /* = 0 */, transfer_type transferType /* = TRANSFER_DEFAULT */, void* offloadInfo /* = nullptr */, int uid, pid_t pid, void* attributes /* = nullptr */);
40+
static ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjm20audio_output_flags_tPFviPvS4_ES4_jRKNS_2spINS_7IMemoryEEEbiNS0_13transfer_typeEPK20audio_offload_info_tiiPK18audio_attributes_t_t ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjm20audio_output_flags_tPFviPvS4_ES4_jRKNS_2spINS_7IMemoryEEEbiNS0_13transfer_typeEPK20audio_offload_info_tiiPK18audio_attributes_t = nullptr;
3741
typedef int32_t(*ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi_t)
3842
(void* thisptr, int32_t streamType, uint32_t sampleRate, uint32_t format, uint32_t channelMask, size_t frameCount /* = 0 */, uint32_t flags /* = 0 */, fake_wp& callback /* = nullptr */, int32_t notificationFrames /* = 0 */, fake_sp& sharedMemory /* = nullptr */, bool threadCanCallJava /* = false */, int32_t audioSessionId /* = 0 */, transfer_type transferType /* = TRANSFER_DEFAULT */, void* offloadInfo /* = nullptr */, int& attributionSource, void* attributes /* = nullptr */, bool doNotReconnect /* = false */, float maxRequiredSpeed /* = 1.0f */, int selectedDeviceId /* = 0 */);
3943
static ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi_t ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi = nullptr;
@@ -64,6 +68,43 @@ struct track_holder {
6468
void* ats;
6569
};
6670

71+
void callbackAdapter(int event, void* userptr, void* info) {
72+
auto user = (MyCallback*) userptr;
73+
switch (event) {
74+
case 0 /* EVENT_MORE_DATA */:
75+
user->onMoreData(*(android::AudioTrack::Buffer*)info);
76+
break;
77+
case 1 /* EVENT_UNDERRUN */:
78+
user->onUnderrun();
79+
break;
80+
case 2 /* EVENT_LOOP_END */:
81+
user->onLoopEnd(*(int32_t*)info);
82+
break;
83+
case 3 /* EVENT_MARKER */:
84+
user->onMarker(*(uint32_t*)info);
85+
break;
86+
case 4 /* EVENT_NEW_POS */:
87+
user->onNewPos(*(uint32_t*)info);
88+
break;
89+
case 5 /* EVENT_BUFFER_END */:
90+
user->onBufferEnd();
91+
break;
92+
case 6 /* EVENT_NEW_IAUDIOTRACk */:
93+
user->onNewIAudioTrack();
94+
break;
95+
case 7 /* EVENT_STREAM_END */:
96+
user->onStreamEnd();
97+
break;
98+
case 8 /* EVENT_NEW_TIMESTAMP */:
99+
user->onNewTimestamp(*(android::AudioTimestamp*)info);
100+
break;
101+
default:
102+
ALOGE("unsupported event %d (user=%p info=%p infoVal=%d)", event, user, info,
103+
info ? *(int32_t*)info : 0);
104+
break;
105+
}
106+
}
107+
67108
extern "C" JNIEXPORT jboolean JNICALL
68109
Java_org_akanework_gramophone_logic_utils_NativeTrack_initDlsym(JNIEnv* env, jobject) {
69110
if (!initLib(env))
@@ -82,13 +123,9 @@ Java_org_akanework_gramophone_logic_utils_NativeTrack_initDlsym(JNIEnv* env, job
82123
DLSYM_OR_RETURN(libutils, ZNK7android7RefBase10createWeakEPKv, false)
83124
DLSYM_OR_RETURN(libutils, ZN7android7RefBase12weakref_type7decWeakEPKv, false)
84125
// TODO support all 5 gazillion variants of set()
85-
if (ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi == nullptr) {
86-
ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi =
87-
(ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi_t)
88-
dlsym(libaudioclient_handle, "_ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi");
89-
if (ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi == nullptr) {
90-
ALOGE("dlsym returned nullptr for _ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi: %s",
91-
dlerror());
126+
DLSYM_OR_ELSE(libaudioclient, ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi) {
127+
DLSYM_OR_ELSE(libaudioclient, ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjm20audio_output_flags_tPFviPvS4_ES4_jRKNS_2spINS_7IMemoryEEEbiNS0_13transfer_typeEPK20audio_offload_info_tiiPK18audio_attributes_t) {
128+
ALOGE("error: found no variant of set()");
92129
return false;
93130
}
94131
}
@@ -119,7 +156,11 @@ Java_org_akanework_gramophone_logic_utils_NativeTrack_create(
119156
}
120157
auto callback = new MyCallback();
121158
callback->incStrong(holder);
122-
((android::AudioTrack*)theTrack)->incStrong(holder);
159+
if (false) {
160+
((android::AudioTrack *) theTrack)->incStrong(holder);
161+
} else {
162+
((android::AudioTrackWithoutDeviceCallback *) theTrack)->incStrong(holder);
163+
}
123164
holder->track = theTrack;
124165
holder->callback = callback;
125166
return (intptr_t)holder;
@@ -129,35 +170,59 @@ extern "C" JNIEXPORT jint JNICALL
129170
Java_org_akanework_gramophone_logic_utils_NativeTrack_doSet(
130171
JNIEnv *, jobject, jlong ptr) {
131172
auto holder = (track_holder*) ptr;
132-
auto refs = holder->callback->createWeak(holder);
133-
fake_wp callback = { .thePtr = holder->callback, .refs = refs };
134-
fake_sp sharedMemory = { .thePtr = nullptr };
135-
auto ret = ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi(
136-
holder->track,
137-
/* streamType = */ 3 /* AUDIO_STREAM_MUSIC */,
138-
/* sampleRate = */ 13370,
139-
/* format = */ 1,
140-
/* channelMask = */ 1,
141-
/* frameCount = */ 0 /* default */,
142-
/* flags = */ 0 /* AUDIO_OUTPUT_FLAG_NONE */,
143-
/* callback = */ callback,
144-
/* notificationFrames = */ 0 /* default */,
145-
/* sharedBuffer = */ sharedMemory,
146-
/* threadCanCallJava = */ true,
147-
/* sessionId = */ 0 /* default */,
148-
/* transferType = */ TRANSFER_SYNC,
149-
/* offloadInfo = */ nullptr,
150-
/* attributionSource = */ *((int*)holder->ats),
151-
/* pAttributes = */ nullptr,
152-
/* doNotReconnect = */ true, // for emulating DIRECT track developer UX
153-
/* maxRequiredSpeed = */ 1.0f,
154-
/* selectedDeviceId = */ 0 /* default */
155-
);
156-
// wp copy constructor increased weak with it's own id, so we're done here
157-
ZN7android7RefBase12weakref_type7decWeakEPKv(refs /* yes, refs */, holder);
158-
// we own attributionSource, so get rid of it
159-
::operator delete(holder->ats);
160-
holder->ats = nullptr;
173+
jint ret = 0;
174+
fake_sp sharedMemory = {.thePtr = nullptr};
175+
if (ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi) {
176+
auto refs = holder->callback->createWeak(holder);
177+
fake_wp callback = {.thePtr = holder->callback, .refs = refs};
178+
ret = ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_t20audio_channel_mask_tm20audio_output_flags_tRKNS_2wpINS0_19IAudioTrackCallbackEEEiRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tRKNS_7content22AttributionSourceStateEPK18audio_attributes_tbfi(
179+
holder->track,
180+
/* streamType = */ 3 /* AUDIO_STREAM_MUSIC */,
181+
/* sampleRate = */ 13370,
182+
/* format = */ 1,
183+
/* channelMask = */ 1,
184+
/* frameCount = */ 0 /* default */,
185+
/* flags = */ 0 /* AUDIO_OUTPUT_FLAG_NONE */,
186+
/* callback = */ callback,
187+
/* notificationFrames = */ 0 /* default */,
188+
/* sharedBuffer = */ sharedMemory,
189+
/* threadCanCallJava = */ true,
190+
/* sessionId = */ 0 /* default */,
191+
/* transferType = */ TRANSFER_SYNC,
192+
/* offloadInfo = */ nullptr,
193+
/* attributionSource = */ *((int *) holder->ats),
194+
/* pAttributes = */ nullptr,
195+
/* doNotReconnect = */ true, // for emulating DIRECT track developer UX
196+
/* maxRequiredSpeed = */ 1.0f,
197+
/* selectedDeviceId = */ 0 /* default */
198+
);
199+
// wp copy constructor increased weak with it's own id, so we're done here
200+
ZN7android7RefBase12weakref_type7decWeakEPKv(refs /* yes, refs */, holder);
201+
// we own attributionSource, so get rid of it
202+
::operator delete(holder->ats);
203+
holder->ats = nullptr;
204+
} else {
205+
ret = ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjm20audio_output_flags_tPFviPvS4_ES4_jRKNS_2spINS_7IMemoryEEEbiNS0_13transfer_typeEPK20audio_offload_info_tiiPK18audio_attributes_t(
206+
holder->track,
207+
/* streamType = */ 3 /* AUDIO_STREAM_MUSIC */,
208+
/* sampleRate = */ 13370,
209+
/* format = */ 1,
210+
/* channelMask = */ 1,
211+
/* frameCount = */ 0 /* default */,
212+
/* flags = */ 0 /* AUDIO_OUTPUT_FLAG_NONE */,
213+
/* callback = */ callbackAdapter,
214+
/* user = */ holder->callback,
215+
/* notificationFrames = */ 0 /* default */,
216+
/* sharedBuffer = */ sharedMemory,
217+
/* threadCanCallJava = */ true,
218+
/* sessionId = */ 0 /* default */,
219+
/* transferType = */ TRANSFER_SYNC,
220+
/* offloadInfo = */ nullptr,
221+
/* uid = */ getuid(),
222+
/* pid = */ getpid(),
223+
/* pAttributes = */ nullptr
224+
);
225+
}
161226
return ret;
162227
}
163228

app/src/main/cpp/aosp_stubs.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ enum transfer_type {
4040
TRANSFER_SYNC_NOTIF_CALLBACK, // synchronous write(), notif EVENT_CAN_WRITE_MORE_DATA
4141
};
4242

43+
typedef void (*legacy_callback_t)(int event, void* user, void *info);
4344
namespace android {
4445
// NOLINTBEGIN
4546
class RefBase {
@@ -131,7 +132,6 @@ namespace android {
131132
IAudioTrackCallback() {
132133
ALOGI("hi from IAudioTrackCallback ctor");
133134
}
134-
protected:
135135
// This event only occurs for TRANSFER_CALLBACK.
136136
virtual inline size_t
137137
onMoreData([[maybe_unused]] const AudioTrack::Buffer &buffer) {
@@ -178,6 +178,12 @@ namespace android {
178178
}
179179
};
180180
};
181+
class AudioTrackWithoutDeviceCallback : public virtual RefBase {
182+
public:
183+
AudioTrackWithoutDeviceCallback() {
184+
ALOGE("if you see this, expect a segfault. this class AudioTrack never was supposed to be instantiated");
185+
}
186+
};
181187
}
182188

183189
inline void android::RefBase::onFirstRef()

app/src/main/cpp/gramophone.cpp

+16-28
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ typedef uint32_t(*ZNK7android10AudioTrack4dumpEiRKNS_6VectorINS_8String16EEE_t)(
4646

4747
static ZNK7android10AudioTrack4dumpEiRKNS_6VectorINS_8String16EEE_t ZNK7android10AudioTrack4dumpEiRKNS_6VectorINS_8String16EEE = nullptr;
4848

49-
typedef status_t(*ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_t)(
49+
typedef status_t(*ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3__t)(
5050
LEGACY_audio_port_role_t, LEGACY_audio_port_type_t, unsigned int *, void *, unsigned int *);
5151

52-
static ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_t ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_ = nullptr;
52+
static ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3__t ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_ = nullptr;
5353
static intptr_t gSampleRateOffset = 0;
5454
static intptr_t gTrackFlagsOffset = 0;
5555

@@ -228,19 +228,14 @@ Java_org_akanework_gramophone_logic_utils_AfFormatTracker_00024Companion_findAfF
228228
return INT32_MIN;
229229
}
230230
if (android_get_device_api_level() >= 28) {
231-
if (!ZN7android11AudioSystem12getAudioPortEP13audio_port_v7) {
231+
DLSYM_OR_ELSE(libaudioclient, ZN7android11AudioSystem12getAudioPortEP13audio_port_v7) {
232232
ZN7android11AudioSystem12getAudioPortEP13audio_port_v7 =
233233
(ZN7android11AudioSystem12getAudioPortEP13audio_port_v7_t)
234-
dlsym(libaudioclient_handle, "_ZN7android11AudioSystem12getAudioPortEP13audio_port_v7");
235-
if (ZN7android11AudioSystem12getAudioPortEP13audio_port_v7 == nullptr) {
236-
ZN7android11AudioSystem12getAudioPortEP13audio_port_v7 =
237-
(ZN7android11AudioSystem12getAudioPortEP13audio_port_v7_t)
238-
dlsym(libaudioclient_handle, "_ZN7android11AudioSystem12getAudioPortEP10audio_port");
239-
if (ZN7android11AudioSystem12getAudioPortEP13audio_port_v7 == nullptr) {
240-
ALOGE("dlsym returned nullptr for _ZN7android11AudioSystem12getAudioPortEP13audio_port_v7: %s",
241-
dlerror());
242-
return INT32_MIN;
243-
}
234+
dlsym(libaudioclient_handle, "_ZN7android11AudioSystem12getAudioPortEP10audio_port");
235+
if (!ZN7android11AudioSystem12getAudioPortEP13audio_port_v7) {
236+
ALOGE("dlsym returned nullptr for _ZN7android11AudioSystem12getAudioPortEP10audio_port: %s",
237+
dlerror());
238+
return INT32_MIN;
244239
}
245240
}
246241
if (gSampleRateOffset == 0 && sampleRate == 0) {
@@ -295,22 +290,15 @@ Java_org_akanework_gramophone_logic_utils_AfFormatTracker_00024Companion_findAfF
295290
free(buffer);
296291
return ret;
297292
} else {
298-
if (!ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_) {
293+
DLSYM_OR_ELSE(libaudioclient, ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_) {
299294
ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_ =
300-
(ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_t)
301-
dlsym(libaudioclient_handle, "_ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_");
302-
if (ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_ ==
303-
nullptr) {
304-
ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_ =
305-
(ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_t)
306-
dlsym(libaudioclient_handle, "_ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP10audio_portS3_");
307-
if (ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_ ==
308-
nullptr) {
309-
ALOGE("dlsym returned nullptr for _ZN7android11AudioSystem14listAudioPortsE17"
310-
"audio_port_role_t17audio_port_type_tPjP10audio_portS3_: %s",
311-
dlerror());
312-
return INT32_MIN;
313-
}
295+
(ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3__t)
296+
dlsym(libaudioclient_handle, "_ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP10audio_portS3_");
297+
if (!ZN7android11AudioSystem14listAudioPortsE17audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_) {
298+
ALOGE("dlsym returned nullptr for ZN7android11AudioSystem14listAudioPortsE17"
299+
"audio_port_role_t17audio_port_type_tPjP13audio_port_v7S3_: %s",
300+
dlerror());
301+
return INT32_MIN;
314302
}
315303
}
316304
// based on AOSP code

0 commit comments

Comments
 (0)