Merge "Add onTuneFailed when canceling tuning operation"

This commit is contained in:
TreeHugger Robot 2022-12-14 10:02:57 +00:00 committed by Android (Google) Code Review
commit 895af958bf
6 changed files with 34 additions and 11 deletions

View file

@ -40,5 +40,6 @@ enum Result {
INVALID_STATE = 3,
NOT_SUPPORTED = 4,
TIMEOUT = 5,
UNKNOWN_ERROR = 6,
CANCELED = 6,
UNKNOWN_ERROR = 7,
}

View file

@ -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().
*/

View file

@ -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.
*/

View file

@ -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();
}

View file

@ -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() {

View file

@ -28,12 +28,15 @@ class WorkerThread {
virtual ~WorkerThread();
void schedule(std::function<void()> task, std::chrono::milliseconds delay);
void schedule(std::function<void()> task, std::function<void()> cancelTask,
std::chrono::milliseconds delay);
void cancelAll();
private:
struct Task {
std::chrono::time_point<std::chrono::steady_clock> when;
std::function<void()> what;
std::function<void()> onCanceled;
};
friend bool operator<(const Task& lhs, const Task& rhs);