blob: f7bb19f19e4e322c8dec3f281263368a2ece3983 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.base;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import java.util.concurrent.atomic.AtomicBoolean;
class SystemMessageHandler extends Handler {
private static final int TIMER_MESSAGE = 1;
private static final int DELAYED_TIMER_MESSAGE = 2;
// Native class pointer set by the constructor of the SharedClient native class.
private int mMessagePumpDelegateNative = 0;
// Used to ensure we have at most one TIMER_MESSAGE pending at once.
private AtomicBoolean mTimerFired = new AtomicBoolean(true);
// Used to insert TIMER_MESSAGE on the front of the system message queue during startup only.
// This is a wee hack, to give a priority boost to native tasks during startup as they tend to
// be on the critical path. (After startup, handling the UI with minimum latency is more
// important).
private boolean mStartupComplete = false;
private final long mStartupCompleteTime = System.currentTimeMillis() + 2000;
private final boolean startupComplete() {
if (!mStartupComplete && System.currentTimeMillis() > mStartupCompleteTime) {
mStartupComplete = true;
}
return mStartupComplete;
}
private SystemMessageHandler(int messagePumpDelegateNative) {
mMessagePumpDelegateNative = messagePumpDelegateNative;
}
@Override
public void handleMessage(Message msg) {
if (msg.what == TIMER_MESSAGE) {
mTimerFired.set(true);
}
while (nativeDoRunLoopOnce(mMessagePumpDelegateNative)) {
if (startupComplete()) {
setTimer();
break;
}
}
}
@CalledByNative
private void setTimer() {
if (!mTimerFired.getAndSet(false)) {
// mTimerFired was already false.
return;
}
if (startupComplete()) {
sendEmptyMessage(TIMER_MESSAGE);
} else {
sendMessageAtFrontOfQueue(obtainMessage(TIMER_MESSAGE));
}
}
// If millis <=0, it'll send a TIMER_MESSAGE instead of
// a DELAYED_TIMER_MESSAGE.
@SuppressWarnings("unused")
@CalledByNative
private void setDelayedTimer(long millis) {
if (millis <= 0) {
setTimer();
} else {
removeMessages(DELAYED_TIMER_MESSAGE);
sendEmptyMessageDelayed(DELAYED_TIMER_MESSAGE, millis);
}
}
@SuppressWarnings("unused")
@CalledByNative
private void removeTimer() {
removeMessages(TIMER_MESSAGE);
removeMessages(DELAYED_TIMER_MESSAGE);
}
@CalledByNative
private static SystemMessageHandler create(int messagePumpDelegateNative) {
return new SystemMessageHandler(messagePumpDelegateNative);
}
private native boolean nativeDoRunLoopOnce(int messagePumpDelegateNative);
}