Sangkyu Lee c3c58e015f Fix ANR caused by hwuiTask thread
If hwuiTask thread is exited while HWUI renders something,
some tasks can remain unfinished forever.
This can make ANR problem if RenderThread waits this kind of tasks.

According to the current implementation, hwuiTask threads are
exited when HWUI receives trimMemory() callback with level >= 20
and some applications such as SystemUI can receive trimMemory()
with level >= 20 even though they renders something yet.
(For instance, when RecentsActivity in SystemUI is finished,
HWUI receives trimMemory() callback with level >= 20
but SystemUI should still render the status bar and navigation bar.)

This patch prevents the tasks from remaining unfinished and
make the tasks executed immediately if they cannot be added
to their TaskProcessors.

Change-Id: I5bd26439aa5f183b1a7c1ce466362e27554b4d16
2015-01-12 13:10:52 +09:00

69 lines
1.8 KiB
C++

/*
* Copyright (C) 2013 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 ANDROID_HWUI_TASK_PROCESSOR_H
#define ANDROID_HWUI_TASK_PROCESSOR_H
#include <utils/RefBase.h>
#include "Task.h"
#include "TaskManager.h"
namespace android {
namespace uirenderer {
class TaskProcessorBase: public RefBase {
public:
TaskProcessorBase() { }
virtual ~TaskProcessorBase() { };
virtual void process(const sp<TaskBase>& task) = 0;
};
template<typename T>
class TaskProcessor: public TaskProcessorBase {
public:
TaskProcessor(TaskManager* manager): mManager(manager) { }
virtual ~TaskProcessor() { }
bool add(const sp<Task<T> >& task);
virtual void process(const sp<TaskBase>& task) {
sp<Task<T> > realTask = static_cast<Task<T>* >(task.get());
// This is the right way to do it but sp<> doesn't play nice
// sp<Task<T> > realTask = static_cast<sp<Task<T> > >(task);
onProcess(realTask);
}
virtual void onProcess(const sp<Task<T> >& task) = 0;
TaskManager* mManager;
};
template<typename T>
bool TaskProcessor<T>::add(const sp<Task<T> >& task) {
if (mManager) {
sp<TaskProcessor<T> > self(this);
return mManager->addTask(task, self);
}
return false;
}
}; // namespace uirenderer
}; // namespace android
#endif // ANDROID_HWUI_TASK_PROCESSOR_H