void TransactionCallbackInvoker::sendCallbacks() {
std::lock_guard lock(mMutex);
// For each listener
auto completedTransactionsItr = mCompletedTransactions.begin();
while (completedTransactionsItr != mCompletedTransactions.end()) {
auto& [listener, transactionStatsDeque] = *completedTransactionsItr;
ListenerStats listenerStats;
listenerStats.listener = listener;
// For each transaction
auto transactionStatsItr = transactionStatsDeque.begin();
while (transactionStatsItr != transactionStatsDeque.end()) {
auto& transactionStats = *transactionStatsItr;
// If this transaction is still registering, it is not safe to send a callback
// because there could be surface controls that haven't been added to
// transaction stats or mPendingTransactions.
if (isRegisteringTransaction(listener, transactionStats.callbackIds)) {
break;
}
// If we are still waiting on the callback handles for this transaction, stop
// here because all transaction callbacks for the same listener must come in order
auto pendingTransactions = mPendingTransactions.find(listener);
if (pendingTransactions != mPendingTransactions.end() &&
pendingTransactions->second.count(transactionStats.callbackIds) != 0) {
break;
}
// If the transaction has been latched
if (transactionStats.latchTime >= 0 &&
!containsOnCommitCallbacks(transactionStats.callbackIds)) {
if (!mPresentFence) {
break;
}
transactionStats.presentFence = mPresentFence;
}
// Remove the transaction from completed to the callback
listenerStats.transactionStats.push_back(std::move(transactionStats));
transactionStatsItr = transactionStatsDeque.erase(transactionStatsItr);
}
- 如果
latchTime
大于 0,即锁定了 buffer,且 callbackIds
不包含 ON_COMMIT
类型时更新 presentFence
。
transactionStats
移动到局部变量 listenerStats
中,它在上面有声明,类型是 ListenerStats。
- 从
mCompletedTransactions
移除 transactionStats
。
// If the listener has completed transactions
if (!listenerStats.transactionStats.empty()) {
// If the listener is still alive
if (listener->isBinderAlive()) {
// Send callback. The listener stored in listenerStats
// comes from the cross-process setTransactionState call to
// SF. This MUST be an ITransactionCompletedListener. We
// keep it as an IBinder due to consistency reasons: if we
// interface_cast at the IPC boundary when reading a Parcel,
// we get pointers that compare unequal in the SF process.
interface_cast<ITransactionCompletedListener>(listenerStats.listener)
->onTransactionCompleted(listenerStats);
if (transactionStatsDeque.empty()) {
listener->unlinkToDeath(mDeathRecipient);
completedTransactionsItr =
mCompletedTransactions.erase(completedTransactionsItr);
} else {
completedTransactionsItr++;
}
} else {
completedTransactionsItr =
mCompletedTransactions.erase(completedTransactionsItr);
}
} else {
completedTransactionsItr++;
}
}
if (mPresentFence) {
mPresentFence.clear();
}
}