Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d7483327 authored by Weilin Xu's avatar Weilin Xu
Browse files

Add onTuneFailed when canceling tuning operation

Due to RadioTuner API documentation, onTuneFailed should be called
when a pending tuning operation is canceled. Therefore, a new
result value Canceled was added in broadcast radio HAL. The
onTuneFailed callback for pending tuning operations in default HAL
was implemented by adding whatIfCanceled function field in Task
struct in WorkerThread utils class.

Bug: 257337458
Test: atest RadioTunerTest#cancel_whenTune
Test: atest RadioTunerTest#cancel_whenSeek
Change-Id: I901ab2cc3561082e5f11a9f6c33db044fc9bc28b
parent 9e6aba51
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -40,5 +40,6 @@ enum Result {
  INVALID_STATE = 3,
  NOT_SUPPORTED = 4,
  TIMEOUT = 5,
  UNKNOWN_ERROR = 6,
  CANCELED = 6,
  UNKNOWN_ERROR = 7,
}
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ oneway interface ITunerCallback {
     * @param result {@link Result#TIMEOUT} in case that tune(), seek() or
     *               step() is not completed within
     *               @link IBroadcastRadio#TUNER_TIMEOUT_MS}
     *               or {@link Result#CANCELED} if the command was canceled.
     * @param selector A ProgramSelector structure passed from tune() call;
     *                 empty for step() and seek().
     */
+6 −0
Original line number Diff line number Diff line
@@ -54,6 +54,12 @@ enum Result {
     */
    TIMEOUT,

    /**
     * Error used when a tune, seek, step or operation is canceled before
     * being processed.
     */
    CANCELED,

    /**
     * Error that does not follow into the error categories above.
     */
+7 −4
Original line number Diff line number Diff line
@@ -238,7 +238,8 @@ ScopedAStatus BroadcastRadio::tune(const ProgramSelector& program) {
        }
        callback->onCurrentProgramInfoChanged(programInfo);
    };
    mThread->schedule(task, kTuneDelayTimeMs);
    auto cancelTask = [program, callback]() { callback->onTuneFailed(Result::CANCELED, program); };
    mThread->schedule(task, cancelTask, kTuneDelayTimeMs);

    return ScopedAStatus::ok();
}
@@ -258,6 +259,7 @@ ScopedAStatus BroadcastRadio::seek(bool directionUp, bool skipSubChannel) {

    const auto& list = mVirtualRadio.getProgramList();
    std::shared_ptr<ITunerCallback> callback = mCallback;
    auto cancelTask = [callback]() { callback->onTuneFailed(Result::CANCELED, {}); };
    if (list.empty()) {
        mIsTuneCompleted = false;
        auto task = [callback]() {
@@ -265,7 +267,7 @@ ScopedAStatus BroadcastRadio::seek(bool directionUp, bool skipSubChannel) {

            callback->onTuneFailed(Result::TIMEOUT, {});
        };
        mThread->schedule(task, kSeekDelayTimeMs);
        mThread->schedule(task, cancelTask, kSeekDelayTimeMs);

        return ScopedAStatus::ok();
    }
@@ -298,7 +300,7 @@ ScopedAStatus BroadcastRadio::seek(bool directionUp, bool skipSubChannel) {
        }
        callback->onCurrentProgramInfoChanged(programInfo);
    };
    mThread->schedule(task, kSeekDelayTimeMs);
    mThread->schedule(task, cancelTask, kSeekDelayTimeMs);

    return ScopedAStatus::ok();
}
@@ -352,7 +354,8 @@ ScopedAStatus BroadcastRadio::step(bool directionUp) {
        }
        callback->onCurrentProgramInfoChanged(programInfo);
    };
    mThread->schedule(task, kStepDelayTimeMs);
    auto cancelTask = [callback]() { callback->onTuneFailed(Result::CANCELED, {}); };
    mThread->schedule(task, cancelTask, kStepDelayTimeMs);

    return ScopedAStatus::ok();
}
+15 −6
Original line number Diff line number Diff line
@@ -18,14 +18,13 @@

namespace android {

using std::chrono::milliseconds;
using std::chrono::steady_clock;
using std::function;
using std::lock_guard;
using std::mutex;
using std::priority_queue;
using std::this_thread::sleep_for;
using std::unique_lock;
using std::chrono::milliseconds;
using std::chrono::steady_clock;
using std::this_thread::sleep_for;

bool operator<(const WorkerThread::Task& lhs, const WorkerThread::Task& rhs) {
    return lhs.when > rhs.when;
@@ -47,16 +46,26 @@ WorkerThread::~WorkerThread() {
}

void WorkerThread::schedule(function<void()> task, milliseconds delay) {
    auto cancelTask = []() {};
    schedule(std::move(task), cancelTask, delay);
}

void WorkerThread::schedule(function<void()> task, function<void()> cancelTask,
                            milliseconds delay) {
    auto when = steady_clock::now() + delay;

    lock_guard<mutex> lk(mMut);
    mTasks.push(Task({when, task}));
    mTasks.push(Task({when, std::move(task), std::move(cancelTask)}));
    mCond.notify_one();
}

void WorkerThread::cancelAll() {
    lock_guard<mutex> lk(mMut);
    priority_queue<Task>().swap(mTasks);  // empty queue
    while (!mTasks.empty()) {
        auto task = mTasks.top();
        task.onCanceled();
        mTasks.pop();
    }
}

void WorkerThread::threadLoop() {
Loading