Skip to content

Commit 3be15fd

Browse files
committed
wip
1 parent 952754e commit 3be15fd

File tree

2 files changed

+56
-19
lines changed

2 files changed

+56
-19
lines changed

app/src/main/cpp/NativeTrack.cpp

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ struct track_holder {
113113
void* deviceCallback = nullptr;
114114
jobject thiz = nullptr;
115115
jmethodID onAudioDeviceUpdate = nullptr;
116+
jmethodID nativeGetFlags = nullptr;
116117
void* ats = nullptr;
117118
bool deathEmulation = false;
118119
bool died = false;
@@ -531,6 +532,7 @@ Java_org_akanework_gramophone_logic_utils_NativeTrack_create(
531532
if (myParcel == nullptr) {
532533
ALOGE("myParcel is NULL");
533534
::operator delete(theTrack);
535+
delete holder;
534536
return 0;
535537
}
536538
auto ats = ::operator new(ATTRIBUTION_SOURCE_SIZE);
@@ -592,7 +594,7 @@ Java_org_akanework_gramophone_logic_utils_NativeTrack_set(
592594
return INT32_MIN;
593595
}
594596
if (android_get_device_api_level() < 30 && (contentId != 0 || syncId != 0)) {
595-
ALOGE("Tuner supported since Android 11.x, (contentId != 0 || syncId != 0) is wrong");
597+
ALOGE("Tuner supported since Android 11, (contentId != 0 || syncId != 0) is wrong");
596598
return INT32_MIN;
597599
}
598600
auto holder = (track_holder*) ptr;
@@ -896,8 +898,19 @@ Java_org_akanework_gramophone_logic_utils_NativeTrack_getRealPtr(
896898

897899
extern "C" JNIEXPORT jint JNICALL
898900
Java_org_akanework_gramophone_logic_utils_NativeTrack_flagsFromOffset(
899-
JNIEnv *, jobject, jlong ptr) {
901+
JNIEnv * env, jobject, jlong ptr, jobject proxy) {
900902
auto holder = (track_holder*) ptr;
903+
if (android_get_device_api_level() >= 26) {
904+
if (proxy == nullptr) {
905+
ALOGE("flagsFromOffset: O+ but proxy is null");
906+
return INT32_MIN;
907+
}
908+
if (!holder->nativeGetFlags) {
909+
ALOGE("flagsFromOffset: O+ but nativeGetFlags is null");
910+
return INT32_MIN;
911+
}
912+
return env->CallIntMethod(proxy, holder->nativeGetFlags);
913+
}
901914
size_t extra;
902915
switch (android_get_device_api_level()) {
903916
#if 0
@@ -916,6 +929,7 @@ Java_org_akanework_gramophone_logic_utils_NativeTrack_flagsFromOffset(
916929
return (int32_t)*(uint32_t*)((uintptr_t)holder->track + 0x2c4);
917930
#else
918931
return (int32_t)*(uint32_t*)((uintptr_t)holder->track + 0x2d0);
932+
#endif
919933
#endif
920934
case 25:
921935
case 24:
@@ -925,7 +939,6 @@ Java_org_akanework_gramophone_logic_utils_NativeTrack_flagsFromOffset(
925939
return (int32_t)*(uint32_t*)((uintptr_t)holder->track + 0x23c);
926940
#else
927941
return (int32_t)*(uint32_t*)((uintptr_t)holder->track + 0x248);
928-
#endif
929942
#endif
930943
case 23:
931944
#ifdef __LP64__
@@ -1043,8 +1056,20 @@ Java_org_akanework_gramophone_logic_utils_NativeTrack_getProxy(JNIEnv* env, jobj
10431056
ALOGE("getProxy should only be called on N+");
10441057
return nullptr;
10451058
}
1046-
auto track = ((track_holder*)ptr)->track;
1059+
auto holder = (track_holder*)ptr;
1060+
auto track = holder->track;
10471061
jclass at = env->FindClass("android/media/AudioTrack");
1062+
if (at == nullptr) {
1063+
ALOGE("android/media/AudioTrack does not exist?!");
1064+
return nullptr;
1065+
}
1066+
if (android_get_device_api_level() >= 26) {
1067+
holder->nativeGetFlags = env->GetMethodID(at, "native_get_flags", "()I");
1068+
if (holder->nativeGetFlags == nullptr) {
1069+
ALOGE("getProxy: didn't find android/media/AudioTrack.native_get_flags()I");
1070+
return nullptr;
1071+
}
1072+
}
10481073
jmethodID ctor = env->GetMethodID(at, "<init>", "(J)V");
10491074
if (ctor == nullptr) {
10501075
ALOGE("getProxy: didn't find android/media/AudioTrack.<init>(J)V");
@@ -1060,9 +1085,9 @@ Java_org_akanework_gramophone_logic_utils_NativeTrack_getProxy(JNIEnv* env, jobj
10601085
ALOGE("getProxy: didn't find android/media/AudioTrack.baseRegisterPlayer(J)V");
10611086
return nullptr;
10621087
}
1063-
jmethodID setId = env->GetMethodID(at, "native_setPlayerIId", "(J)V");
1088+
jmethodID setId = env->GetMethodID(at, "native_setPlayerIId", "(I)V");
10641089
if (setId == nullptr) {
1065-
ALOGW("getProxy: didn't find android/media/AudioTrack.native_setPlayerIId(J)V");
1090+
ALOGW("getProxy: didn't find android/media/AudioTrack.native_setPlayerIId(I)V");
10661091
env->ExceptionClear(); // TODO is this needed?
10671092
//return nullptr; TODO on which API levels should this work?
10681093
}

app/src/main/kotlin/org/akanework/gramophone/logic/utils/NativeTrack.kt

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -333,25 +333,40 @@ class NativeTrack(context: Context, attributes: AudioAttributes, streamType: Int
333333
proxy = try {
334334
getProxy(ptr, this.sessionId)
335335
} catch (t: Throwable) {
336-
Log.e(TAG, Log.getStackTraceString(t)); null
336+
try {
337+
dtor(ptr)
338+
} catch (t2: Throwable) {
339+
throw NativeTrackException("dtor() threw exception after getProxy() threw exception: " +
340+
Log.getStackTraceString(t2), t)
341+
}
342+
throw NativeTrackException("getProxy() threw exception", t)
343+
}
344+
if (proxy == null) {
345+
try {
346+
dtor(ptr)
347+
} catch (t: Throwable) {
348+
throw NativeTrackException("dtor() threw exception after getProxy() returned null, " +
349+
"check prior logs", t)
350+
}
351+
throw NativeTrackException("getProxy() returned null, check prior logs")
337352
}
338353
routingListener = object : AudioRouting.OnRoutingChangedListener {
339354
override fun onRoutingChanged(router: AudioRouting?) {
340355
this@NativeTrack.onRoutingChanged()
341356
}
342357
}
343-
proxy?.addOnRoutingChangedListener(routingListener, null)
358+
proxy.addOnRoutingChangedListener(routingListener, null)
344359
} else {
345360
proxy = null
346361
routingListener = null
347362
}
348-
if (proxy != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
363+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
349364
codecListener = object : AudioTrack.OnCodecFormatChangedListener {
350365
override fun onCodecFormatChanged(audioTrack: AudioTrack, info: AudioMetadataReadMap?) {
351366
this@NativeTrack.onCodecFormatChanged(info)
352367
}
353368
}
354-
proxy.addOnCodecFormatChangedListener(MoreExecutors.directExecutor(), codecListener)
369+
proxy!!.addOnCodecFormatChangedListener(MoreExecutors.directExecutor(), codecListener)
355370
} else codecListener = null
356371
myState = State.ALIVE
357372
Log.e("hi", "dump:${AfFormatTracker.dumpInternal(getRealPtr(ptr))}")
@@ -387,20 +402,20 @@ class NativeTrack(context: Context, attributes: AudioAttributes, streamType: Int
387402
doNotReconnect: Boolean, transferMode: Int, contentId: Int, syncId: Int,
388403
encapsulationMode: Int): Int
389404
private external fun getRealPtr(@Suppress("unused") ptr: Long): Long
390-
private external fun flagsFromOffset(@Suppress("unused") ptr: Long): Int
405+
private external fun flagsFromOffset(@Suppress("unused") ptr: Long, @Suppress("unused") proxy: AudioTrack?): Int
391406
private external fun notificationFramesActFromOffset(@Suppress("unused") ptr: Long): Int
392407
private external fun dtor(@Suppress("unused") ptr: Long)
393408
@RequiresApi(Build.VERSION_CODES.N)
394-
private external fun getProxy(@Suppress("unused") ptr: Long, @Suppress("unused") sessionId: Int): AudioTrack
409+
private external fun getProxy(@Suppress("unused") ptr: Long, @Suppress("unused") sessionId: Int): AudioTrack?
395410

396411
fun release() {
397412
myState = State.RELEASED
398413
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && codecListener != null) {
399-
proxy?.removeOnCodecFormatChangedListener(codecListener)
414+
proxy!!.removeOnCodecFormatChangedListener(codecListener)
400415
}
401416
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
402-
proxy?.removeOnRoutingChangedListener(routingListener)
403-
proxy?.release() // this doesn't free native obj because we hold extra strong ref, cleared in dtor()
417+
proxy!!.removeOnRoutingChangedListener(routingListener)
418+
proxy.release() // this doesn't free native obj because we hold extra strong ref, cleared in dtor()
404419
}
405420
dtor(ptr)
406421
}
@@ -447,10 +462,7 @@ class NativeTrack(context: Context, attributes: AudioAttributes, streamType: Int
447462
// TODO document L/M not stripping all flags, only direct / offload / fast
448463
if (myState == State.RELEASED)
449464
throw IllegalStateException("state is $myState")
450-
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
451-
AfFormatTracker.getFlagsFromDump(dump())
452-
?: throw IllegalStateException("getFlags failed, check prior logs")
453-
else flagsFromOffset(ptr) // TODO use proxy get_flags on N/O
465+
return flagsFromOffset(ptr, proxy)
454466
}
455467

456468
fun notificationFramesAct(): Int {

0 commit comments

Comments
 (0)