Skip to content

Commit 59f224a

Browse files
committed
wip
1 parent 6ba2729 commit 59f224a

File tree

5 files changed

+219
-69
lines changed

5 files changed

+219
-69
lines changed

app/src/main/cpp/NativeTrack.cpp

+139-36
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,14 @@ static ZN7android10AudioTrackC1Ev_t ZN7android10AudioTrackC1Ev = nullptr;
3636
typedef void(*ZN7android7RefBase12weakref_type7decWeakEPKv_t)(void* thisptr, void* id);
3737
static ZN7android7RefBase12weakref_type7decWeakEPKv_t ZN7android7RefBase12weakref_type7decWeakEPKv = nullptr;
3838
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 */);
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 */, int32_t transferType /* = TRANSFER_DEFAULT */, void* offloadInfo /* = nullptr */, int uid, pid_t pid, audio_attributes_t* attributes /* = nullptr */);
4040
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;
4141
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)
42-
(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 */);
42+
(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 */, int32_t transferType /* = TRANSFER_DEFAULT */, void* offloadInfo /* = nullptr */, int& attributionSource, audio_attributes_t* attributes /* = nullptr */, bool doNotReconnect /* = false */, float maxRequiredSpeed /* = 1.0f */, int selectedDeviceId /* = 0 */);
4343
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;
44+
typedef int32_t(*ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjm20audio_output_flags_tPFviPvS4_ES4_iRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tjiPK18audio_attributes_tbfi_t)
45+
(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 */, int32_t transferType /* = TRANSFER_DEFAULT */, void* offloadInfo /* = nullptr */, uid_t uid, pid_t pid, audio_attributes_t* attributes /* = nullptr */, bool doNotReconnect /* = false */, float maxRequiredSpeed /* = 1.0f */, int selectedDeviceId /* = 0 */);
46+
static ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjm20audio_output_flags_tPFviPvS4_ES4_iRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tjiPK18audio_attributes_tbfi_t ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjm20audio_output_flags_tPFviPvS4_ES4_iRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tjiPK18audio_attributes_tbfi = nullptr;
4447

4548
class MyCallback : public virtual android::AudioTrack::IAudioTrackCallback {
4649
public:
@@ -124,9 +127,11 @@ Java_org_akanework_gramophone_logic_utils_NativeTrack_initDlsym(JNIEnv* env, job
124127
DLSYM_OR_RETURN(libutils, ZN7android7RefBase12weakref_type7decWeakEPKv, false)
125128
// TODO support all 5 gazillion variants of set()
126129
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()");
129-
return false;
130+
DLSYM_OR_ELSE(libaudioclient, ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjm20audio_output_flags_tPFviPvS4_ES4_iRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tjiPK18audio_attributes_tbfi) {
131+
DLSYM_OR_ELSE(libaudioclient, ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjm20audio_output_flags_tPFviPvS4_ES4_jRKNS_2spINS_7IMemoryEEEbiNS0_13transfer_typeEPK20audio_offload_info_tiiPK18audio_attributes_t) {
132+
ALOGE("error: found no variant of set()");
133+
return false;
134+
}
130135
}
131136
}
132137
return true;
@@ -156,10 +161,11 @@ Java_org_akanework_gramophone_logic_utils_NativeTrack_create(
156161
}
157162
auto callback = new MyCallback();
158163
callback->incStrong(holder);
159-
if (false) {
164+
if (android_get_device_api_level() >= 33) {
165+
// virtual inheritance, let's have the compiler generate the vtable stuff
160166
((android::AudioTrack *) theTrack)->incStrong(holder);
161167
} else {
162-
((android::AudioTrackWithoutDeviceCallback *) theTrack)->incStrong(holder);
168+
ZNK7android7RefBase9incStrongEPKv(theTrack, holder);
163169
}
164170
holder->track = theTrack;
165171
holder->callback = callback;
@@ -168,59 +174,151 @@ Java_org_akanework_gramophone_logic_utils_NativeTrack_create(
168174

169175
extern "C" JNIEXPORT jint JNICALL
170176
Java_org_akanework_gramophone_logic_utils_NativeTrack_doSet(
171-
JNIEnv *, jobject, jlong ptr) {
177+
JNIEnv * env, jobject, jlong ptr, jint streamType, jint sampleRate, jint format,
178+
jint channelMask, jint frameCount, jint trackFlags, jint sessionId, jfloat maxRequiredSpeed,
179+
jint selectedDeviceId, jint bitRate, jlong durationUs, jboolean hasVideo,
180+
jboolean isStreaming, jint bitWidth, jint offloadBufferSize, jint usage,
181+
jint encapsulationMode, jint contentId, jint syncId, jint contentType, jint source,
182+
jint attrFlags, jstring inTags, jint notificationFrames, jboolean doNotReconnect,
183+
jint transferMode) {
172184
auto holder = (track_holder*) ptr;
173185
jint ret = 0;
174186
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) {
187+
const char* tags = env->GetStringUTFChars(inTags, nullptr);
188+
union {
189+
audio_offload_info_t newInfo;
190+
audio_offload_info_t_legacy oldInfo;
191+
} offloadInfo;
192+
union {
193+
audio_attributes_t newAttrs;
194+
audio_attributes_t_legacy oldAttrs;
195+
} audioAttributes;
196+
if (android_get_device_api_level() >= 28) {
197+
offloadInfo.newInfo = {
198+
.version = AUDIO_MAKE_OFFLOAD_INFO_VERSION(0, 2),
199+
.size = sizeof(audio_offload_info_t),
200+
.sample_rate = (uint32_t)sampleRate,
201+
.channel_mask = (uint32_t)channelMask,
202+
.format = (uint32_t)format,
203+
.stream_type = streamType,
204+
.bit_rate = (uint32_t)bitRate,
205+
.duration_us = durationUs,
206+
.has_video = (bool)hasVideo,
207+
.is_streaming = (bool)isStreaming,
208+
.bit_width = (uint32_t)bitWidth,
209+
.offload_buffer_size = (uint32_t)offloadBufferSize,
210+
.usage = usage,
211+
.encapsulation_mode = encapsulationMode,
212+
.content_id = contentId,
213+
.sync_id = syncId,
214+
};
215+
audioAttributes.newAttrs = audio_attributes_t {
216+
.content_type = contentType,
217+
.usage = usage,
218+
.source = source,
219+
.flags = (uint32_t)attrFlags,
220+
};
221+
audioAttributes.newAttrs.tags[255] = '\0';
222+
strncpy(audioAttributes.newAttrs.tags, tags, 255);
223+
} else {
224+
offloadInfo.oldInfo = {
225+
.version = AUDIO_MAKE_OFFLOAD_INFO_VERSION(0, 1),
226+
.size = sizeof(audio_offload_info_t_legacy),
227+
.sample_rate = (uint32_t)sampleRate,
228+
.channel_mask = (uint32_t)channelMask,
229+
.format = (uint32_t)format,
230+
.stream_type = streamType,
231+
.bit_rate = (uint32_t)bitRate,
232+
.duration_us = durationUs,
233+
.has_video = (bool)hasVideo,
234+
.is_streaming = (bool)isStreaming,
235+
.bit_width = (uint32_t)bitWidth,
236+
.offload_buffer_size = (uint32_t)offloadBufferSize,
237+
.usage = usage,
238+
};
239+
audioAttributes.oldAttrs = {
240+
.content_type = contentType,
241+
.usage = usage,
242+
.source = source,
243+
.flags = (uint32_t)attrFlags,
244+
};
245+
audioAttributes.oldAttrs.tags[255] = '\0';
246+
strncpy(audioAttributes.oldAttrs.tags, tags, 255);
247+
}
248+
env->ReleaseStringUTFChars(inTags, tags);
249+
if (holder->ats != nullptr) {
176250
auto refs = holder->callback->createWeak(holder);
177251
fake_wp callback = {.thePtr = holder->callback, .refs = refs};
178252
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(
179253
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 */,
254+
/* streamType = */ streamType /* AUDIO_STREAM_MUSIC */,
255+
/* sampleRate = */ sampleRate,
256+
/* format = */ format,
257+
/* channelMask = */ channelMask,
258+
/* frameCount = */ frameCount /* default */,
259+
/* flags = */ trackFlags /* AUDIO_OUTPUT_FLAG_NONE */,
186260
/* callback = */ callback,
187-
/* notificationFrames = */ 0 /* default */,
261+
/* notificationFrames = */ notificationFrames,
188262
/* sharedBuffer = */ sharedMemory,
189263
/* threadCanCallJava = */ true,
190-
/* sessionId = */ 0 /* default */,
191-
/* transferType = */ TRANSFER_SYNC,
192-
/* offloadInfo = */ nullptr,
264+
/* sessionId = */ sessionId,
265+
/* transferType = */ transferMode,
266+
/* offloadInfo = */ &offloadInfo,
193267
/* attributionSource = */ *((int *) holder->ats),
194-
/* pAttributes = */ nullptr,
195-
/* doNotReconnect = */ true, // for emulating DIRECT track developer UX
196-
/* maxRequiredSpeed = */ 1.0f,
197-
/* selectedDeviceId = */ 0 /* default */
268+
/* pAttributes = */ &audioAttributes.newAttrs,
269+
/* doNotReconnect = */ doNotReconnect,
270+
/* maxRequiredSpeed = */ maxRequiredSpeed,
271+
/* selectedDeviceId = */ selectedDeviceId
198272
);
199273
// wp copy constructor increased weak with it's own id, so we're done here
200274
ZN7android7RefBase12weakref_type7decWeakEPKv(refs /* yes, refs */, holder);
201275
// we own attributionSource, so get rid of it
202276
::operator delete(holder->ats);
203277
holder->ats = nullptr;
278+
} else if (ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjm20audio_output_flags_tPFviPvS4_ES4_iRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tjiPK18audio_attributes_tbfi) {
279+
ret = ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjm20audio_output_flags_tPFviPvS4_ES4_iRKNS_2spINS_7IMemoryEEEb15audio_session_tNS0_13transfer_typeEPK20audio_offload_info_tjiPK18audio_attributes_tbfi(
280+
holder->track,
281+
/* streamType = */ streamType,
282+
/* sampleRate = */ sampleRate,
283+
/* format = */ format,
284+
/* channelMask = */ channelMask,
285+
/* frameCount = */ frameCount,
286+
/* flags = */ trackFlags,
287+
/* callback = */ callbackAdapter,
288+
/* user = */ holder->callback,
289+
/* notificationFrames = */ notificationFrames,
290+
/* sharedBuffer = */ sharedMemory,
291+
/* threadCanCallJava = */ true,
292+
/* sessionId = */ sessionId,
293+
/* transferType = */ transferMode,
294+
/* offloadInfo = */ &offloadInfo,
295+
/* uid = */ getuid(),
296+
/* pid = */ getpid(),
297+
/* pAttributes = */ &audioAttributes.newAttrs,
298+
/* doNotReconnect = */ doNotReconnect,
299+
/* maxRequiredSpeed = */ maxRequiredSpeed,
300+
/* selectedDeviceId = */ selectedDeviceId
301+
);
204302
} else {
205303
ret = ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tjm20audio_output_flags_tPFviPvS4_ES4_jRKNS_2spINS_7IMemoryEEEbiNS0_13transfer_typeEPK20audio_offload_info_tiiPK18audio_attributes_t(
206304
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 */,
305+
/* streamType = */ streamType,
306+
/* sampleRate = */ sampleRate,
307+
/* format = */ format,
308+
/* channelMask = */ channelMask,
309+
/* frameCount = */ frameCount,
310+
/* flags = */ trackFlags,
213311
/* callback = */ callbackAdapter,
214312
/* user = */ holder->callback,
215-
/* notificationFrames = */ 0 /* default */,
313+
/* notificationFrames = */ notificationFrames,
216314
/* sharedBuffer = */ sharedMemory,
217315
/* threadCanCallJava = */ true,
218-
/* sessionId = */ 0 /* default */,
219-
/* transferType = */ TRANSFER_SYNC,
220-
/* offloadInfo = */ nullptr,
221-
/* uid = */ getuid(),
316+
/* sessionId = */ sessionId,
317+
/* transferType = */ transferMode,
318+
/* offloadInfo = */ &offloadInfo,
319+
/* uid = */ (int32_t)getuid(),
222320
/* pid = */ getpid(),
223-
/* pAttributes = */ nullptr
321+
/* pAttributes = */ &audioAttributes.newAttrs
224322
);
225323
}
226324
return ret;
@@ -237,7 +335,12 @@ Java_org_akanework_gramophone_logic_utils_NativeTrack_dtor(
237335
JNIEnv *, jobject, jlong ptr) {
238336
auto holder = (track_holder*) ptr;
239337
// RefBase will call the dtor
240-
((android::AudioTrack*)holder->track)->decStrong(holder);
338+
if (android_get_device_api_level() >= 33) {
339+
// virtual inheritance, let's have the compiler generate the vtable stuff
340+
((android::AudioTrack *) holder->track)->decStrong(holder);
341+
} else {
342+
ZNK7android7RefBase9decStrongEPKv(holder->track, holder);
343+
}
241344
holder->callback->decStrong(holder);
242345
delete holder;
243346
}

0 commit comments

Comments
 (0)