aboutsummaryrefslogtreecommitdiff
path: root/externals/oboe/apps/OboeTester/app/src/main/cpp/TestErrorCallback.h
diff options
context:
space:
mode:
authorswurl <swurl@swurl.xyz>2025-05-31 02:33:02 -0400
committerswurl <swurl@swurl.xyz>2025-05-31 02:33:02 -0400
commit6c655321e6b04b8648802e296bb5ca11d290ae68 (patch)
tree5c906511e4a2910ce8b806bb9d763b524c28619e /externals/oboe/apps/OboeTester/app/src/main/cpp/TestErrorCallback.h
parentc0cceff365f754f8859f4c9a0362ebdba7ea388b (diff)
Move dead submodules in-tree
Signed-off-by: swurl <swurl@swurl.xyz>
Diffstat (limited to 'externals/oboe/apps/OboeTester/app/src/main/cpp/TestErrorCallback.h')
-rw-r--r--externals/oboe/apps/OboeTester/app/src/main/cpp/TestErrorCallback.h114
1 files changed, 114 insertions, 0 deletions
diff --git a/externals/oboe/apps/OboeTester/app/src/main/cpp/TestErrorCallback.h b/externals/oboe/apps/OboeTester/app/src/main/cpp/TestErrorCallback.h
new file mode 100644
index 0000000000..d7ce8980da
--- /dev/null
+++ b/externals/oboe/apps/OboeTester/app/src/main/cpp/TestErrorCallback.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OBOETESTER_TEST_ERROR_CALLBACK_H
+#define OBOETESTER_TEST_ERROR_CALLBACK_H
+
+#include "common/OboeDebug.h"
+#include "oboe/Oboe.h"
+#include <thread>
+
+/**
+ * This code is an experiment to see if we can cause a crash from the ErrorCallback.
+ */
+class TestErrorCallback {
+public:
+
+ oboe::Result open();
+ oboe::Result start();
+ oboe::Result stop();
+ oboe::Result close();
+
+ int test();
+
+ int32_t getCallbackMagic() {
+ return mCallbackMagic.load();
+ }
+
+protected:
+
+ std::atomic<int32_t> mCallbackMagic{0};
+
+private:
+
+ void cleanup() {
+ mDataCallback.reset();
+ mErrorCallback.reset();
+ mStream.reset();
+ }
+
+ class MyDataCallback : public oboe::AudioStreamDataCallback { public:
+
+ oboe::DataCallbackResult onAudioReady(
+ oboe::AudioStream *audioStream,
+ void *audioData,
+ int32_t numFrames) override;
+
+ };
+
+ class MyErrorCallback : public oboe::AudioStreamErrorCallback {
+ public:
+
+ MyErrorCallback(TestErrorCallback *parent): mParent(parent) {}
+
+ virtual ~MyErrorCallback() {
+ // If the delete occurs before onErrorAfterClose() then this bad magic
+ // value will be seen by the Java test code, causing a failure.
+ // It is also possible that this code will just cause OboeTester to crash!
+ mMagic = 0xdeadbeef;
+ LOGE("%s() called", __func__);
+ }
+
+ void onErrorBeforeClose(oboe::AudioStream *oboeStream, oboe::Result error) override {
+ LOGE("%s() - error = %s, parent = %p",
+ __func__, oboe::convertToText(error), &mParent);
+ // Trigger a crash by "deleting" this callback object while in use!
+ // Do not try this at home. We are just trying to reproduce the crash
+ // reported in #1603.
+ std::thread t([this]() {
+ this->mParent->cleanup(); // Possibly delete stream and callback objects.
+ LOGE("onErrorBeforeClose called cleanup!");
+ });
+ t.detach();
+ // There is a race condition between the deleting thread and this thread.
+ // We do not want to add synchronization because the object is getting deleted
+ // and cannot be relied on.
+ // So we sleep here to give the deleting thread a chance to win the race.
+ usleep(10 * 1000);
+ }
+
+ void onErrorAfterClose(oboe::AudioStream *oboeStream, oboe::Result error) override {
+ // The callback was probably deleted by now.
+ LOGE("%s() - error = %s, mMagic = 0x%08X",
+ __func__, oboe::convertToText(error), mMagic.load());
+ mParent->mCallbackMagic = mMagic.load();
+ }
+
+ private:
+ TestErrorCallback *mParent;
+ // This must match the value in TestErrorCallbackActivity.java
+ static constexpr int32_t kMagicGood = 0x600DCAFE;
+ std::atomic<int32_t> mMagic{kMagicGood};
+ };
+
+ std::shared_ptr<oboe::AudioStream> mStream;
+ std::shared_ptr<MyDataCallback> mDataCallback;
+ std::shared_ptr<MyErrorCallback> mErrorCallback;
+
+ static constexpr int kChannelCount = 2;
+};
+
+#endif //OBOETESTER_TEST_ERROR_CALLBACK_H